perm filename ERRCON.MAC[IP,SYS] blob
sn#725249 filedate 1983-10-01 generic text, type T, neo UTF8
TITLE ERRCON - MONITOR DETECTED ERROR HANDLING ROUTINES - V2036
SUBTTL T. HASTINGS/TH/CHW/TW/RCC/DAL 25 JUL 80
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VERRCN,2036 ;THIS MACRO PUTS VERSION NO. IN STORAGE MAP AND GLOB
ENTRY ERRCON ;ALWAYS LOAD ERRCON(IF LIB SEARCH)
ERRCON::
SUBTTL CLOCK LEVEL APR ERROR HANDLING
;HERE ON PI 7 CLOCK INTERRUPT TO PROCESS APR ERRORS FOR INDIVIDUAL JOBS
;.CPAEF HOLDS COMMUNICATION FLAGS SET BY APR PI INTERRUPT LEVEL
;CALL: MOVE S,.CPAEF
; JUMPN S,APRILM ;COME HERE IF ANYTHING HAPPENED
; RETURN TO RESCHEDULE NEW USER
APRILM::MOVEM S,.CPSAC## ;HERE ON ANY APR ERROR OR MEM PARITY
SKIPN J,.CPJOB## ;CURRENT JOB ON THIS CPU
SETOM .CPNJE## ;MAKE SURE NULL JOBS AC'S ARE RESTORED
JUMPGE S,APRIL1 ;REQUEST TO SCAN MEMORY FOR PARITY OR NXM?
TLNN S,(CP.PSX!CP.CSX) ;YES IS THIS JUST A PRINT JOB MESSAGES REQUEST?
JRST APRIL2 ;YES--GO LOOP THRU JOBS AND PRINT MESSAGES TO TTY'S
PUSHJ P,PARSWP ;NO--SWEEP CORE (AND FLAG JOBS ON KI10)
IFN FTKI10,<
SKIPL .CPMPC## ;ANY SERIOUS ERRORS?
JRST APRIL2 ;NO
PUSHJ P,PARHL1 ;YES--ANNOUNCE ON CTY AND HALT
STOPCD (.+1,HALT,SME) ;++SERIOUS MEMORY ERROR
HRRZS .CPMPC## ;TRY TO CONTINUE-PROBABLY A VERY BAD IDEA
>
APRIL2: MOVE J,HIGHJB## ;HIGHEST JOB NUMBER
TRNE S,UE.NXM ;NXM INSTEAD OF PARITY ERROR?
JRST NXMLOP ;YES--REPORT NXM TO ALL JOBS AFFECTED
;NO--REPORT PARITY TO ALL JOBS AFFECTED
; FALL INTO PARLOP
;;LOOP TO SCAN ALL JOBS, ZAP BAD ONES AND PRINT PARITY ERROR MESSAGE
PARLOP: MOVEI T1,JS.MPE ;MEM PARITY FOR JOB
TDNN T1,JBTSTS##(J) ;JOB HAVE MEM PAR IN LOW/HIGH SEG OR UPMP?
JRST PARLO1 ;NO--KEEP LOOKING
ANDCAM T1,JBTSTS##(J) ;YES, CLEAR IN JOB STATUS WORD
SKIPN JBTADR##(J) ;IS LOW SEG STILL IN CORE? (NO IF SWAPOUT ERROR)
JRST PARLO1 ;NO--KEEP LOOKING
PUSHJ P,ZAPHIM ;RETURN ALL HIS RESOURCES
PUSHJ P,PARSTP ;STOP JOB AND PRINT MESSAGE
PARLO1: SOJG J,PARLOP ;LOOP OVER ALL JOBS
IFN FTMP,<
PUSHJ P,GETMM## ;GET THE MM
JRST .-1 ;MUST WAIT
>
PUSHJ P,CPINXF ;FIX CORE TABLES, IF NEEDED
SKIPA ;CORMAX WAS DECREASED
JRST PARXIT ;ALL JOBS NOT ZAPPED CAN CONTINUE TO RUN
IFN FTMP,<
PUSHJ P,GIVMM## ;RETURN THE MM
>
;HERE IF CORMAX WAS DECREASED SO ALL JOBS MUST BE SCANNED AND ANY
; WHICH ARE TOO BIG TO BE SWAPPED IN MUST BE ZAPPED ALSO
SETZ J, ;FIRST CALL ARG. TO JBSTBG
PARLP2: MOVE T1,CORMAX## ;GET CURRENT VALUE OF CORMAX
PUSHJ P,JBSTBG ;SEE IF THIS JOB IS NOW TOO BIG TO RUN
JRST PARXI1 ;ALL JOBS HAVE BEEN LOOKED AT
PUSHJ P,PARSTP ;STOP THE JOB AND TELL THE USER
JRST PARLP2 ;KEEP GOING
;EXIT FROM PARITY SWEEP AND PRINT ROUTINE
PARXIT:
IFN FTMP,<
PUSHJ P,GIVMM## ;RETURN THE MM
>
PARXI1: HRROI S,UE.PEF ;CLEAR PARITY ERROR FLAG
ANDCAB S,.CPAEF## ;OTHER APR ERRORS?
JUMPN S,APRILM ;YES, GO PROCESS THEM
POPJ P, ;RETURN
NXMLOP: MOVEI T1,JS.NXM ;JOB OVERLAPS NXM BIT
TDNN T1,JBTSTS##(J) ;DOES THIS JOB OVERLAP NXM?
JRST NXMLP1 ;NO, KEEP LOOKING
ANDCAM T1,JBTSTS##(J) ;CLEAR THE BIT
IFN FTMONL,<
CAME J,MOFLPG## ;IS THIS THE JOB THAT TYPED SET MEM ON?
>
SKIPN JBTADR##(J) ;DOES THIS JOB HAVE CORE IN CORE?
JRST NXMLP1 ;IF NO TO EITHER, DO NOTHING
PUSHJ P,ZAPUSR ;ZAP THE PROGRAM
IFN FTLOCK,<
PUSHJ P,UNLOCK## ;UNLOCK IT IF LOCKED
>
PUSHJ P,NXMSTP ;STOP THE JOB AND TELL THE USER WHAT HAPPENED
NXMLP1: SOJG J,NXMLOP ;LOOP OVER ALL JOBS ON THE SYSTEM
IFN FTMP,<
PUSHJ P,GETMM## ;GET THE MM
JRST .-1 ;MUST WAIT
>
PUSHJ P,CPINXF ;FIX CORE ALLOCATION TABLES, ETC.
SKIPA ;CORMAX WAS DECREASED
JRST NXMXIT ;ALL JOBS NOT ZAPPED CAN CONTINUE TO RUN
IFN FTMP,<
PUSHJ P,GIVMM##
>
;HERE IF CORMAX WAS DECREASED SO ALL JOBS MUST BE SCANNED AND ANY
; WHICH ARE TOO BIG TOO BE SWAPPED IN MUST BE ZAPPED
MOVEI J,0 ;STARTING WITH JOB 0,
NXMLP2: MOVE T1,CORMAX## ; AND THE CURRENT VALUE OF CORMAX
PUSHJ P,JBSTBG ;SEE IF THIS JOB IS NOW TO BIG TO BE RUN
JRST NXMXI1 ;ALL JOBS HAVE BEEN LOOKED AT
PUSHJ P,NXMSTP ;STOP THE JOB AND TELL THE USER
JRST NXMLP2 ;SEE IF ANYMORE JOBS ARE TOO BIG
NXMXIT:
IFN FTMP,<
PUSHJ P,GIVMM##
>
NXMXI1: HRROI S,UE.NXM ;CLEAR SOFTWARE NXM FLAG
ANDCAB S,.CPAEF## ; ..
JUMPN S,APRILM ;GO PROCESS OTHER ERRORS IF THEY EXIST
POPJ P, ;OTHERWISE, RETURN
;SUBROUTINE TO PRINT MEM PAR ERROR FOR JOB N AND STOP JOB
;CALL: MOVE J,JOB NO
; PUSHJ P,PARSTP
; ALWAYS RETURN
PARSTP: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
PUSHJ P,ZAPPGM## ;"CORE 0"
JSP T1,ERRPNT ;PRINT STANDARD ERROR IN JOB MESSAGE
ASCIZ /Memory parity error/
JRST NXMST1 ;PRINT MESSAGE AND STOP HIM
;SUBROUTINE TO PRINT NXM ERROR FOR JOB N AND STOP JOB
NXMSTP: PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
PUSHJ P,ZAPPGM## ;"CORE 0"
JSP T1,ERRPNT ;PRINT ERROR MESSAGE FOR THE USER
ASCIZ /Non-existent memory error/
AOS .CPNJA## ;COUNT NUMBER OF JOBS ZAPPED BECAUSE OF NXM
NXMST1: MOVE T2,.CPMPP## ;PC WHERE THE ERROR OCCURRED
PJRST PCPNT ;PRINT INFO FOR USER AND STOP HIM
;SUBROUTINE CALLED TO HALT CPU ON SERIOUS ERROR IN MEMORY
PARHLT::CONO PI,PI.OFF ;NO INTERRUPTS DURING TYPEOUT
PUSHJ P,PARHL1 ;TYPE OUT APPROPRIATE MESSAGE ON CTY
IFN FTMP,<
SETOM DIELOK## ;GIVE DIE LOCK BACK
>
STOPCD (.,HALT,FEM) ;++FATAL ERROR IN MONITOR
PARHL1: MOVEI T1,CTYWAT## ;NON-PI CTY TYPEOUT ROUTINE ADDRESS
MOVEM T1,.CPTOA## ;MAKE IT THE ONE TO USE HERE
IFN FTKL10,<
PUSHJ P,SVPPC## ;MAKE SURE WE'RE IN SECONDARY PROTOCOL ON KL10
>
SKIPN .CPREP## ;A PARITY ERROR? (NOT NXM)
JRST NXMCTY ;NO, NXM REPORT NXM INSTEAD
PUSHJ P,INLMES## ;PRINT MESSAGE TO INFORM OPER OF HALT
ASCIZ /
πππππ?Non-recoverable memory parity error in monitor.
[CPU Halt]
/
POPJ P, ;RETURN AND HALT
NXMCTY: PUSHJ P,INLMES## ;INFORM OPR OF HALT
ASCIZ /
πππππ?Non-existent memory detected in monitor.
[CPU Halt]
/
POPJ P, ;RETURN AND HALT
;ROUTINE TO SCAN MEMORY FOR PARITY OR NXM ERRORS (APR PI OR PI 7)
;CALLED AT APR PI IF MAY BE A SERIOUS ERROR IN MONITOR AND PIS IN PROGRESS
;CALL:
; MOVE J,CURRENT JOB NO. ON THIS CPU
; MOVE S,.CPAEF SWEEP REQUEST BITS
; PUSHJ P,PARSWP
; ALWAYS RETURNS - LH .CPMPC SET NEG. IF SERIOUS MONITOR PARITY
; S PRESERVED
PARSWP::HRRZ U,.CPCTN## ;GET CPU'S CTY LINE NUMBER
HRRZ U,LINTAB##(U) ;NOW GET HIS LDB
TRNN S,UE.PEF ;PARITY ERROR?
JRST NXMSWP ;NO, SWEEP FOR NXM
MOVEI T1,SDELIM ;GET ADDRESS OF TEXT
PUSHJ P,CONMES## ;PRINT START DELIMITER
MOVEI T1,[ASCIZ /Memory parity scan initiated by /]
PUSHJ P,CONMES## ;ANNOUNCE SWEEP
PUSHJ P,PRCHCP ;FINISH OFF MESSAGE
SETOM .CPREP## ;TELL REPORTERS WHICH ERROR TYPE TO REPORT
SETOM .CPPAA## ;YES, SET PARITY AND OF BAD ADDRESSES TO -1
SETOM .CPPAC## ;SET PARITY AND OF BAD CONTENTS TO -1
SETZM .CPPOA## ;SET PARITY OR OF BAD ADDRESSES TO 0
SETZM .CPPOC## ;SET PARITY OR OF BAD CONTENTS TO 0
AOS .CPPSC## ;INCREMENT PARITY SWEEP COUNT
SETZM .CPPTS## ;SET NO OF PARITIES THIS SWEEP TO 0
IFN FTKL10,<
PUSHJ P,SVPPC## ;DON'T LET FE TIME US OUT WHILE SWEEPING
>
PUSHJ P,@.CPMPS## ;CALL CPU DEPENDENT CORE SWEEP ROUTINE
SETZM .CPLPP## ;CLEAR LAST PARITY ERROR PC
SKIPE .CPPTS## ;WERE SOME BAD WORDS FOUND ON SWEEP?
SKIPA T1,[EDELIM] ;YES--JUST GET END DELIMITER TEXT
MOVEI T1,[ASCIZ /Nothing was found.
***************
/] ;NO--TELL THEM THAT
PUSHJ P,CONMES## ;PRINT IT
MOVEI T1,.ERSPR ;GET CODE FOR DAEMON
HRL T1,.CPSLF## ;GET CPU CDB
PUSHJ P,DAEEIM## ;POKE DAEMON
SKIPE .CPPTS## ;IF SOME REAL ERRORS WERE FOUND
POPJ P, ; THEN JUST RETURN NOW
TLNN S,(CP.PSX) ;DID PROCESSOR DETECT PARITY?
AOSA .CPPCS## ;NO, COUNT CHANNEL SPURIOUS COUNT
AOSA .CPSPE## ;YES, COUNT PROCESSOR SPURIOUS COUNT
POPJ P, ;RETURN - CHANNEL SPURIOUS ERROR
;FALL INTO NEXT PAGE IF PROCESSOR SPURIOUS
IFN FTKI10,<
;HERE ON NO PARITY FOUND ON SWEEP - COULD BE READ - PAUSE - WRITE
MOVE T1,.CPAPC## ;MEMORY PARITY PC (STORED BEFORE SWEEP)
TLNN T1,(XC.USR) ;WAS PC IN USER MODE?
HRROS .CPMPC## ;NO, SERIOUS BECAUSE HAVE TO ASSUME
; PARITY WAS IN MONITOR AREA - HALT FLAG
; SO PRINT ON CTY
MOVE J,.CPJOB## ;CURRENT JOB # THIS CPU
PUSHJ P,HGHSPE## ;FLAG ALL JOBS IF HIGH SEG DOES NOT HAVE DISK COPY
; SINCE PARITY MAY BE IN HIGH SEG, ELSE SWAP OUT ALL
; JOBS USING HIGH SEG.
PUSHJ P,PARJB1 ;ALWAYS FLAG CURRENT USER
; SINCE PARITY MAY BE IN HIS JOB (READ-PAUSE-WRITE)
>;END IFN FTKI10
POPJ P, ;RETURN - PROCESSOR SPURIOUS ERROR
;ROUTINE TO PRINT WHO REQUESTED SCAN, WHERE, AND AT WHAT TIME
PRCHCP: TLNN S,(CP.PSX) ;REQUESTED BY CPU?
JRST PRCHC1 ;NO--BY CHANNEL
MOVEI T1,[ASCIZ /CPU/]
PUSHJ P,CONMES## ;APPEND "CPU"
MOVEI T1,5 ;START WITH CPU 5
MOVE T2,S ;COPY OF S
PRCHC0: LSH T2,-1 ;NEXT CPU
TLNN T2,(CP.PS5←-1) ;IS IT THIS CPU?
SOJGE T1,PRCHC0 ;NO--TRY NEXT
PUSHJ P,RADX10 ;YES--APPEND CPU NUMBER
JRST PRCHC3 ;CONTINUE
PRCHC1: MOVEI T1,[ASCIZ /channel /]
PUSHJ P,CONMES## ;APPEND "CHANNEL"
MOVEI T1,7 ;START WITH CHANNEL 7
MOVE T2,S ;COPY OF S
PRCHC2: LSH T2,-1 ;NEXT CHANNEL
TLNN T2,(CP.CS7←-1) ;IS IT THIS CHANNEL?
SOJGE T1,PRCHC2 ;NO--TRY NEXT
PUSHJ P,RADX10 ;YES--APPEND CHANNEL NUMBER
PRCHC3: MOVEI T1,[ASCIZ / on /]
PUSHJ P,CONMES## ;APPEND "ON"
MOVE T2,.CPLOG## ;SCANNING CPU'S (THIS) NAME
PUSHJ P,PRNAME ;APPEND IT
MOVEI T1,[ASCIZ / on /]
PUSHJ P,CONMES## ;APPEND "ON"
PUSHJ P,DAYTIM## ;FINISH WITH DATE AND TIME
POPJ P, ;RETURN
;SUBROUTINE TO SWEEP CORE LOOKING FOR NON-EXISTENT MEMORY
NXMSWP: MOVEI T1,SDELIM ;GET ADDRESS OF TEXT
PUSHJ P,CONMES## ;PRINT START DELIMITER
MOVEI T1,[ASCIZ /Non-existent memory scan initiated by /]
PUSHJ P,CONMES## ;ANNOUNCE SWEEP
PUSHJ P,PRCHCP ;FINISH SWEEP MESSAGE
SETZM .CPREP## ;SET NXM FLAG
SETOM .CPNAA## ;CLEAR AND OF NON-EXISTENT ADDRESSES
SETZM .CPNOA## ; AND OR OF NON-EXISTENT ADDRESSES
SETZM .CPNJA## ;NO JOBS AFFECTED YET
AOS .CPNSC## ;INCREMENT THE NUMBER OF NXM SWEEPS DONE
SETZM .CPNTS## ;CLEAR THE COUNT OF NXMS SEEN THIS SWEEP
IFN FTKL10,<
PUSHJ P,SVPPC## ;DON'T LET FE TIME US OUT
>
PUSHJ P,@.CPMPS## ;SWEEP CORE
SETZM .CPLPP## ;CLEAR LAST ERROR PC
SKIPE .CPNTS## ;ANY NON-EXISTANT MEMORY SEEN?
SKIPA T1,[EDELIM] ;YES--JUST GET END DELIMITER
MOVEI T1,[ASCIZ /Nothing was found.
***************
/] ;NO--TELL THEM THAT
PUSHJ P,CONMES## ;PRINT IT
MOVEI T1,.ERSNX ;GET DAEMON CODE
HRL T1,.CPSLF## ;GET CPU CDB
PUSHJ P,DAEEIM## ;POKE DAEMON
SKIPE .CPNTS## ;IF SOME REAL ERRORS WERE FOUND
POPJ P, ; THEN JUST RETURN NOW
TLNE S,(CP.PSX) ;DID THE PROCESSOR SEE THE NXM?
AOSA .CPSNE## ;YES, COUNT PROCESSOR SPURIOUS COUNT
AOS .CPNCS## ;NO, COUNT SPURIOUS CHANNEL NXMS
POPJ P, ;RETURN
;DELIMITER TEXT FOR CTY SYSTEM ERROR MESSAGES
SDELIM::ASCIZ /
ππ***************
/
EDELIM::ASCIZ /***************
/
;SUBROUTINE TO RECORD MEM PARITY DATA FOR EACH BAD WORD
;CALL: MOVE T1,REL ADDR WITHIN HIGH OR LOW SEG,
; -1 IF NEITHER IN MONITOR NOR HIGH NOR LOW SEG
; MOVE P1,ABS ADR OF BAD WORD (22 BITS)
; MOVE S,.CPAEF FLAG BITS
; MOVE P2,CONTENTS OF BAD WORD
; PUSHJ P,PARRBD ;RECORD BAD DATA
; ALWAYS RETURN EVEN IF SERIOUS ERROR
;CALLED FROM CPU DPENDENT MEMORY SWEEP LOOP
PARRBD::TRNN S,UE.PEF ;A PARITY ERROR?
JRST NXMRBD ;NO, RECORD NXM
AOS .CPTPE## ;INCREMENTATION NO OF MEM PARITY ERRORS FOR SYSTEM
AOS T2,.CPPTS## ;INCREMENT NO OF PARITY ERRORS THIS SWEEP
SOJG T2,PARSEC ;IS THIS THE FIRST ERROR THIS SWEEP?
MOVEM P1,.CPMPA## ;YES, SAVE BAD ADDRESS
MOVEM P2,.CPMPW## ;BAD CONTENTS
IFN FTKI10,<
PUSH P,T1 ;SAVE T1
>
MOVEI T1,[ASCIZ /Parity errors detected:
/]
PUSHJ P,CONMES## ;ANNOUNCE ERRORS SEEN
PARSEC: MOVEI T1,[ASCIZ / at /]
PUSHJ P,CONMES## ;PRINT "AT"
MOVE T1,P1 ;BAD ADDRESS
PUSHJ P,PRTDI8 ;PRINT IT
MOVEI T1,[ASCIZ / (phys.), Contents = /]
PUSHJ P,CONMES## ;PRINT MORE MESSAGE
MOVE T1,P2 ;GET BAD CONTENTS
PUSHJ P,HWDPNT ;PRINT IT
IFN FTKL10,<
MOVEI T1,[ASCIZ /, ERA = /]
PUSHJ P,CONMES## ;CONTINUE MESSAGE
MOVE T1,.CPSTE## ;GET ERA FROM LAST SCAN TRAP
PUSHJ P,HWDPNT ;PRINT IT
>
PUSHJ P,CRLF## ;END WITH CRLF
ANDM P1,.CPPAA## ;ACCUM AND OF BAD ADDRESSES THIS SWEEP
ANDM P2,.CPPAC## ;ACCUM AND OF BAD CONTENTS THIS SWEEP
IORM P1,.CPPOA## ;ACCUM OR OF BAD ADDRESSES THIS SWEEP
IORM P2,.CPPOC## ;ACCUM OR OF BAD CONTENTS THIS SWEEP
MOVE T2,.CPPTS## ;PARITY ERRORS FOUND ON CURRENT SCAN
CAIG T2,M.CBAT## ;IS THERE ROOM FOR THIS BAD ADR IN TABLE?
MOVEM P1,.CPBAT##-1(T2) ;YES, STORE IN I-TH POSITION IN CDB
MOVEM P1,.CPLPA## ;ALWAYS STORE LAST PARITY ADDRESS
IFN FTKL10!FTKS10,<
POPJ P, ;RETURN
>
;NEXT PAGE FOR KI10'S
IFN FTKI10,<
POP P,T1 ;RESTORE T1
JUMPE T1,CPOPJ## ;IF ADDR NOT IN MONITOR OR A JOB, JUST RETURN
PARSC1: JUMPN J,PARJHS ;WAS ERROR IN A JOB AND NOT MONITOR?
HRROS .CPMPC## ;NO, FLAG AS SERIOUS ERROR - MUST HALT AFTER PRINT
POPJ P, ;RETURN (CURRENT JOB ALREADY FLAGGED TO STOP)
;HERE IF BAD JOB OR HIGH SEG - T1 STILL HAS REL. ADR. WITHIN SEG
PARJHS: JUMPL J,PARJOB ;FLAG JOB BAD IF IN UPMP
CAILE J,JOBMAX## ;IS PARITY ERROR IN LOW SEGMENT?
PJRST HGHPAR## ;NO, GO FIND ALL JOBS USING THIS HIGH SEG
; AND CALL PARJOB FOR EACH ONE WHICH DOESN'T HAVE
; HIGH SEG DISK COPY
PJRST PARJOB ;GO FLAG JOB
>;END IFN FTKI10
;HERE TO RECORD NON-EXISTANT MEMORY FOUND ON THE SWEEP
NXMRBD: AOS .CPTNE## ;COUNT TOTAL NUMBER OF NXMS SEEN
AOS T2,.CPNTS## ;COUNT UP THE NUMBER SEEN THIS SWEEP
SOJG T2,NXMSEC ;JUMP IF NOT THE FIRST NXM THIS SWEEP
MOVEM P1,.CPMNA## ;FIRST THIS SWEEP, RECORD BAD ADDRESS
PUSH P,T1 ;SAVE T1
MOVEI T1,[ASCIZ /Non-existent memory detected:
/]
PUSHJ P,CONMES## ;ANNOUNCE ERRORS
NXMSEC: MOVEI T1,[ASCIZ / at /]
PUSHJ P,CONMES## ;PRINT "AT"
MOVE T1,P1 ;GET BAD ADDRESS
PUSHJ P,PRTDI8 ;PRINT IT
MOVEI T1,[ASCIZ / (phys.)
/]
PUSHJ P,CONMES## ;FINISH MESSAGE
ANDM P1,.CPNAA## ;AND OF BAD ADDRESSES
IORM P1,.CPNOA## ;OR OF BAD ADDRESSES
MOVE T2,.CPNTS## ;NUMBER OF NXM'S SEEN ON CURRENT SCAN
CAIG T2,M.CBAT## ;HAVE THE MAXIMUM NUMBER OF BAD ADDRESSES BEEN STORED?
MOVEM P1,.CPBAT##-1(T2) ;NO, STORE THIS ONE
MOVEM P1,.CPLNA## ;ALWAYS STORE THE LAST BAD ADDRESS
MOVE T1,P1 ;BAD ADDRESS TO T1
LSH T1,W2PLSH## ;CONVERT TO BAD PAGE
IDIVI T1,↑D36 ;36 BITS/WORD
MOVE T2,BITTBL##(T2) ;BIT POSITION WITHIN THE WORD
IORM T2,NXMTAB##(T1) ;MARK THIS PAGE AS NON-EXISTANT
POP P,T1 ;RESTORE T1
JUMPE T1,CPOPJ## ;RETURN IF BAD ADDRESS NOT IN THE MONITOR OR A JOB
JUMPN J,NXMJHS ;JUMP IF BAD ADDRESS IN SOME SEGMENT
HRROS .CPMPC## ;BAD ADDRESS IS IN THE MONITOR,
; FLAG THIS AS A SERIOUS ERROR
POPJ P, ;AND CONTINUE THE SWEEP
NXMJHS: JUMPL J,NXMJH2 ;FLAG JOB IF IN UPMP
CAILE J,JOBMAX## ;BAD ADDRESS IN A HIGH SEGMENT?
PJRST HGHPAR## ;YES, FLAG HIGH SEGMENT AS IN NXM
NXMJH2: MOVEI T1,JS.NXM ;BAD ADDRESS IN A LOW SEGMENT, FLAG
IORM T1,JBTSTS##(J) ; THE JOB TO BE STOPPED
POPJ P, ;AND RETURN TO CONTINUE THE SWEEP
;SUBROUTINE TO FLAG JOB FOR MESSAGE - IF APR DETECTED (RATHER THAN CHANNEL)
;CALL: MOVE J,JOB NUMBER
; MOVE S.CPAEF ;CPU OR CHAN DETECTED PARITY
; PUSHJ P,PARJOB
; ALWAYS RETURN
;CALLED ON CPU0 AND CPU1
PARJOB: TLNN S,(CP.PSX) ;PARITY FOUND BY ANY PROCESSOR?
POPJ P, ;NO, RETURN
;YES, FALL INTO PARJB1
;SUBROUTINE TO FLAG JOB FOR MEM PAR MESSAGE - ALWAYS
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,PARJB1
; ALWAYS RETURN
PARJB1::MOVSI T1,JACCT ;CLEAR JACCT SO THAT DAMAGED PROGRAM
ANDCAM T1,JBTSTS##(J) ; WILL NOT HAVE PRIVILEGES
MOVEI T1,JS.MPE ;MEMORY PARITY ERROR IN JOB FLAG
IORM T1,JBTSTS##(J) ;SET JOB STATUS WORD
POPJ P, ;RETURN
;SUBROUTINE TO RETURN ALL JOBS WHICH ARE OR WOULD BE TOO BIG TO RUN
; IF MEMORY HAS DROPPED OFF LINE OR WERE TO BE SET OFF LINE
;CALLING SEQUENCE:
; MOVE T1,NEW VALUE OF CORMAX
; MOVEI J,0 ;FIRST CALL
; PUSHJ P,JBSTBG
;RETURN CPOPJ IF NO JOB OR NONE OF THE REMAINING JOBS ARE TOO BIG, CPOPJ1
; IF A JOB IS TOO BIG, J = JOB NUMBER OF THE JOB WHICH IS TOO BIG
JBSTBG::PUSH P,T1 ;SAVE THE NEW VALUE OF CORMAX
JBSTB1: ADDI J,1 ;LOOK AT THE NEXT JOB
CAMLE J,HIGHJB## ;LOOKED AT ALL JOBS?
JRST TPOPJ## ;YES, GIVE ALL DONE RETURN
PUSHJ P,SEGSIZ## ;SIZE OF THIS JOBS LOW SEGMENT
MOVE T1,T2 ;SAVE THAT
PUSH P,J ;SAVE THE JOB NUMBER
MOVEI T2,0 ;ASSUME THAT THE JOB DOESN'T HAVE A HIGH SEGMENT
SKIPLE J,JBTSGN##(J) ;DOES IT?
PUSHJ P,SEGSIZ## ;YES, GET THE SIZE OF THE HIGH SEGMENT
POP P,J ;RESTORE THE JOB NUMBER
ADD T1,T2 ;SIZE OF THE JOB IN PAGES
LSH T1,P2WLSH## ;SIZE OF THE JOB IN WORDS
CAMLE T1,(P) ;IS THE JOB TOO BIG TO CONTINUE TO RUN?
JRST TPOPJ1## ;YES, SKIP RETURN TO CALLER
JRST JBSTB1 ;NO, LOOK AT THE NEXT JOB
;HERE IF NO MEM PARITY - MUST BE APR ERROR
APRIL1: SETZM .CPAEF## ;CLEAR APR ERROR FLAG (IN CASE OTHER APR ERRORS
; OCCUR BEFORE EXIT THIS CODE)
MOVE T1,.CPAPC## ;ERROR PC STORED BY APR PI LEVEL
; (REAL PC MAY HAVE BEEN ZEROED TO DISMISS INT)
MOVEM T1,.CPPC## ;STORE IN CURRENT USER PROTECTED PC
; (SO DUMP WILL KNOW REAL PC)
IFN FTCCIN!FTDAEM,<
MOVEM T1,.JDAT+JOBPD1## ;STORE FOR POSSIBLE .JBINT
>
TRNE S,AP.PPV ;PROPRIETARY VIOLATION?
JRST APRPPV ;YES
TRNN S,AP.ILM ;ILLEGAL MEMORY?
JRST APRNXM ;NO
IFN FTPI,<
SIGNAL C$IMR ;SIGNAL ILL MEM REF CONDITION
SKIPA ;USER DOESN'T WANT TRAP
POPJ P, ;WANTS INTERCEPT GO TO USER
>
HRRZ T1,.CPAPC## ;PC STORED BY APR INTERRUPT
CAMLE T1,.CPREL## ;IS PC IN BOUNDS(LOW SEG)?
PUSHJ P,SEGILM## ;NO, IS PC IN LEGAL MEMORY IN HIGH SEG?
JRST APRILR ;YES, GO PRINT ILL MEM REF
JSP T1,ERRPTU ;NO, PRINT PC EXCEEDS MEM BOUND
ASCIZ /PC out of bounds/
JRST APRSCD ;PRINT LOC, THEN STOP JOB
APRILR: JSP T1,ERRPTU
ASCIZ /Illegal memory reference/
JRST APRSCD ;PRINT LOC, THEN STOP JOB
APRNXM: TRNN S,AP.NXM ;NON-EX MEM?
JRST APRPDL ;NO
IFN FTPI,<
SIGNAL C$NXM ;SIGNAL JOB
SKIPA ;NOT INTERRESTED
POPJ P, ;TRAP TO USER
> ;END FTPI
SKIPE J,.CPJOB## ;JOB RUNNING WHEN NXM HAPPENED
PUSHJ P,GIVRES ;RETURN RESOURCES, ETC.
JSP T1,ERRPTU ;YES
NXMMES::ASCIZ /Non-existent memory/
JRST APRSCD ;PRINT LOC, THEN STOP JOB
APRPPV: JSP T1,ERRPTU
ASCIZ /Proprietary violation/
JRST APRSCD
;SUBROUTINE TO PRINT JOB NUMBER AND PROG NAME ON OPR
;CALL: MOVEI T1,JOB STATUS BIT (JS.MPE OR JS.DPM)
; MOVE U,LINE DATA BLOCK FOR CTY OR OPR
; PUSHJ P,OPRPJN ;PRINT JOB NUMBERS
; ALWAYS RETURN
OPRPJN: PUSH P,T1 ;SAVE JOB STATUS BIT TO TEST FOR MESSAGE
PUSHJ P,INLMES## ;TELL HIM JOB NOS. SO HE WILL RESTART
; SYSTEM JOBS IF THEY HAVE PROBLEM
ASCIZ / for job/
MOVE J,HIGHJB## ;HIGHEST JOB NUMBER
;LOOP TO PRINT JOB NOS. AND PROGRAM NAME OF ALL JOBS WITH BAD PARITY
; OR DAEMON PROBLEM MESS
PARLP1: MOVE T1,JBTSTS##(J) ;JOB STATUS WORD
TDNE T1,(P) ;DOES THIS JOB HAVE BAD PARITY OR DAEMON
; PROBLEM? (DEPENDING ON CALLERS ARG)
PUSHJ P,PRJBNM ;YES, PRINT JOB# AND PROGRAM NAME
SOJG J,PARLP1 ;ANY MORE JOBS?
POP P,T1 ;RESTORE STACK
PJRST CRLF## ;NO, PRINT CRLF AND RETURN
;SUBROUTINE TO PRINT SWAP OUT MEM PAR ERROR
;CALL: MOVE J,JOB USING HIGH SEG (WHETHER IN CORE OR NOT)
; PUSHJ P,SWOMES
; ALWAYS RETURN JOB SWAPPED, DAEMON CALLED
SWOMES::MOVSI T1,JERR ;SET JERR SO WE DO NOT
IORM T1,JBTSTS##(J) ;TRY TO INTERCEPT
JSP T1,ERRPNT ;PRINT MESSAGE
ASCIZ /Swap out channel memory parity error/
PJRST APRSCD ;PRINT PC AND STOP JOB
;SUBROUTINE TO PRINT <SPACE> JOB NO. [PROG. NAME]
;CALL:
; MOVE J,JOB NUMBER
; MOVE U,LDB FOR OPR OR CTY
; PUSHJ P,PRJBNM ;PRINT JOB NO. AND PROG. NAME
; ALWAYS RETURN
PRJBNM::PUSHJ P,PRSPC## ;YES, PRINT LEADING SPACE
MOVE T1,J ;PRINT JOB NO.
PUSHJ P,RADX10 ;AS DECIMAL
PUSHJ P,PRLBK## ;PRINT LEFT BRACKET
MOVE T2,JBTPRG##(J) ;PROGRAM NAME
PUSHJ P,PRNAME ;PRINT SO OPER WILL RECOGNIZE HIS JOBS
PUSHJ P,PRRBK## ;PRINT RIGHT BRACKET
POPJ P, ;RETURN
;SUBROUTINE TO CHECK IF JOB HAS BEEN WAITING FOR TWO SUCCESSIVE
; MINUTE CHECKS FOR DAEMON. CALLED ONCE A MINUTE FOR EACH JOB
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,DPMJOB
; YES RETURN - MESSAGE PRINTED ON JOB CONSOLE
; NO RETURN
IFN FTDAEM,< ;DAEMON FEATURE?
DPMJOB::MOVE T1,JBTSTS##(J) ;JOB STATUS WORD
TRNN T1,JS.DPM ;THIS JOB BEEN WAITING FOR 2 CONSECUTIVE MIN?
JRST CPOPJ1## ;NO
PUSHJ P,STDAEM## ;START DAEMON
PJRST DAEDON## ;NO DAEMON
PUSHJ P,TTYFND## ;YES, FIND CONTROLLING TTY
JUMPE U,CPOPJ##
PUSHJ P,DAEPRB ;PRINT PROBLEM WITH DAEMON
PUSHJ P,INLMES## ;TELL USER WHAT SYSTEM IS DOING ABOUT IT
ASCIZ /, operator action requested
/
PJRST TTYSTR## ;START TTY
;SUBROUTINE TO PRINT ON OPR PROBLEM WITH DAEMON
;CALLED ONCE A MIN ONLY IF A JOB IS STILL WAITING
;CALL: PUSHJ P,DPMOPR
DPMOPR::HRRZ U,OPRLDB## ;OPR LINE DATA BLOCK HDR
PUSHJ P,DAEPRB ;PRINT PROBLEM WITH DAEMON
MOVEI T1,JS.DPM ;JOB STATUS BIT - NEED DAEMON PROB MESS.
PJRST OPRPJN ;TELL OPR WHICH JOBS ARE STUCK
;SUBROUTINE TO PRINT PROBLEM WITH DAEMON
;CALL: MOVE U,LINE DATA BLOCK ADR
; PUSHJ P,DAEPRB
DAEPRB: PJSP T1,CONMES## ;PRINT MESSAGE AND RETURN
ASCIZ /
%Problem with DAEMON/
> ;END DAEMON FEATURE
APRPDL: TRNN S,AP.POV ;PUSHDOWN OVERFLOW?
JRST APRLTH ;NO
TLNE T1,USRMOD ;IS PUSHDOWN LIST OVERFLOW IN EXEC UUO?
JRST PRTPOV ;NO - PRINT USER ERROR MESSAGE
STOPCD PRTPV1,DEBUG,EPO, ;++EXEC PDL OV
PRTPV1: AOS EPOCNT## ;NO OF NON-RECOVERABLE MONITOR PDL OVFS
MOVE J,.CPJOB## ;ZAPUSR REQUIRES J SET UP
PUSHJ P,ZAPUSR ;CLEAR ALL DDB'S, CHANS
JRST PRTPV2
APRLTH: TRNN S,XP.LTH ;LOOP IN TRAP HANDLER?
STOPCD CPOPJ##,DEBUG,SAC, ;++STRANGE APR CONDITION
JSP T1,ERRPTU ;TYPE MESSAGE
ASCIZ/Loop in trap handler/
JRST APRSCD ;AND PC OF ERROR
PRTPOV:
IFN FTPI,<
SIGNAL C$PLOV ;SEE IF USER CARES
SKIPA ;DOESN'T
POPJ P, ;HE DOES
>
PRTPV2: JSP T1,ERRPTU ;PRINT ERROR MESSAGE
PDLMES::ASCIZ /Push down list overflow/
APRSCD: MOVE T2,.CPAPC## ;PRINT APR PC
JRST PCPNT ;AS:
; 1)"AT USER LOC XXX" OR
; 2)"AT EXEC LOC XXX; EXEC CALLED FROM
; EXEC/USER LOC YYY
;ADDRESS CHECK ERROR AT ANY LEVEL
;F MUST BE SET UP TO POINT TO OFFENDING DEVICE
ADRERR::
IFN FTPI,<
LDB J,PJOBN## ;OFFENDING JOB'S JOB NUMBER
SIGNAL C$ADCK ;SEE IF USER ENABLED FOR ADDRESS CHECK
SKIPA ;USER DOESN'T WANT TRAP
JRST ERRGOU ;GO TO USER
>
JSP T1,ERRDEV ;GET JOB NO. FROM DEVICE DATA BLOCK
ASCIZ /Address check for /
JRST DEVEXC ;PRINT "DEVICE XXX; EXEC CALLED FROM
; EXEC/USER LOC YYY"
; THEN STOP JOB
;SUBROUTINE TO CLEAR ALL DDB'S, IO CHARS
;CALL WITH JOB NUMBER IN J
ZAPHIM: PUSHJ P,SVEUB## ;MAKE HIM ADDRESSABLE
ZAPHER::PUSHJ P,SWPCLN## ;ZAP THE ACCESS TABLES
PUSHJ P,GIVRSC ;GIVE UP RESOURCES
PJRST ZAPUSC ;PITCH INITED DDB'S
ZAPUSR::JUMPE J,CPOPJ##
PUSHJ P,GIVRSC ;GIVE UP ANY RESOURCES JOB MAY HAVE
CAMN J,.CPJOB## ;CURRENT JOB?
POPJ P, ;YES, GIVE UP INITED DDB'S ON RESET
; (ALL SHARED RESOURCES ALREADY GIVEN UP)
ZAPUSC::HLRZ F,DEVLST## ;LOC OF FIRST DDB
ZAPUS2: LDB T1,PJOBN## ;OWNER OF DDB
MOVEI T2,DEPMSG ;IS THIS DDB CONTROLLED BY MPX
TDNN T2,DEVMSG(F) ;IF SO, GIVE IT UP WHEN WE ZAP MPX
CAME T1,J ;RIGHT GUY OWN IT
SKIPA ;NO, DON'T RELEASE IT
PUSHJ P,RELEA9## ;YES, RELEASE IT
JUMPE F,ZAPUSC ;F=0 IF NETWORK DDB WAS RELEASED
HLRZ F,DEVSER(F)
JUMPN F,ZAPUS2
POPJ P, ;RETURN
;SUBROUTINE TO RESET A JOB WHOSE ASSOCIATED
;HISEG HAD A SWAP INPUT ERROR
ZAPHGH::SKIPN JBTADR##(J)
POPJ P,
PUSHJ P,CLRJOB##
PUSHJ P,ZAPUSR
PJRST ERRSWP
;SUBROUTINE TO RETURN ALL RESOURCES
;CALL WITH J=JOB#
GIVRES::NTGIVE ;RETURN THE NETWORK INTERLOCK
JUMPE J,CPOPJ##
CAMN J,.CPJOB## ;NO DEVICES ACTIVE IF NOT CURRENT JOB
PUSHJ P,IOWAIT## ;WAIT FOR ANY ACTIVE DEVICES TO FINISH
GIVRSC::HLRZ F,SWPDDB##+DEVSER ;START AT FIRST DSK
GIVRS0: MOVE T1,DEVMOD(F) ;IS THIS A DISK?
TLNN T1,DVDSK
IFN FTSPL,<
SKIPGE DEVSPL(F) ;NO, SPOOLED DDB?
CAIA ;YES
>
JRST GIVRS3 ;NO
MOVE S,DEVIOS(F)
LDB T1,PJOBN## ;YES, THIS JOB OWN IT?
CAMN T1,J
PUSHJ P,RETRES## ;YES, RETURN ANY RESOURCES IT OWNS
GIVRS3: PUSHJ P,NXDDB## ;AND TRY NEXT DDB
JRST [JUMPE F,GIVRS1 ;DONE IF 0
CAMN J,.UPMP+.UPJOB
JRST GIVRS0 ;CONTINUE IF JOB IS ADDRESSABLE
JRST GIVRS1] ;NEXT ADDRESSABLE - DONE
JRST GIVRS0 ;TRY NEXT
GIVRS1: SETZ T1, ;START WITH FIRST RESOURCE
DPB T1,PJBSTS## ;MAKE SURE THAT JOB DOESN'T APPEAR
; TO HAVE ACTIVE DISK I/O
GIVRS2: CAMN J,USRTAB##(T1) ;OWNED BY JOB?
PUSHJ P,DVFREE##(T1) ;YES--FREE IT UP
CAIGE T1,AVLNUM## ;DONE YET?
AOJA T1,GIVRS2 ;NO--CONTINUE
PUSHJ P,ADFREE## ;RETURN AU,DA IF OWNED
PUSHJ P,TPFREE## ;FREE UP TAPE KONTROLLERS
IFN FTKL10,<
PUSHJ P,GIVPMR## ;DOES THIS JOB HAVE THE PERFORMANCE METER?
;NO, SO DON'T GIVE IT UP.
;YES, GIVE IT BACK SO OTHERS MAY MEASURE
>;END IFN FTKL10
IFN FTLOCK,<
PUSHJ P,UNLOCK## ;UNLOCK THE JOB IF LOCKED
>
PUSH P,W ;SAVE W
PUSHJ P,FNDPDB## ;FIND JOBS PDB
JRST WPOPJ## ;RETURN IF NONE
SKIPLE .PDDVL##(W) ;ANY LOGICAL NAMES AROUND
PUSHJ P,SETDVF## ;YES,BLAST THEM
JRST WPOPJ## ;RESTORE W AND RETURN
NPDUFL::STOPCD .,STOP,NPU, ;++NULL PUSH-DOWN-LIST UNDERFLOW
;JSR TO HERE FROM INTRPT LOC
$LOW
PIERR::0
EXCH P,PIEPDL
STOPCD .,CPU,PIE, ;++PRIORITY INTERRUPT ERROR
PIEPDL::XWD 0,.
BLOCK 1
$HIGH
SUBTTL COMMON ROUTINES FOR HANDLING ERRORS IN MEMORY
;SUBROUTINE - ABSOLUTE ADDRESS TO SEGMENT NUMBER
;CALL: MOVE P1,ABSOLUTE ADDRESS
; PUSHJ P,CPIASN
; ERROR RETURN IF NOT IN MONITOR OR A HIGH OR LOW SEGMENT OR A UPMP
; OK RETURN J=0 IF IN MONITOR, OR HIGH OR LOW SEG NO., OR -J IF JOB'S UPMP
CPIASN::SETZB T2,J ;ASSUME IN MONITOR (JOB 0 NOT A LEGAL JOB #)
LDB T1,[POINT 13,P1,26] ;SET REL. ADR. FROM ABS. ADR IN MONITOR
MOVE T1,PAGTAB(T1) ;GET PAGTAB ENTRY FOR THIS PAGE
TLNE T1,MONTRB ;IS THIS A MONITOR PAGE?
JRST CPOPJ1## ;YES, GIVE OK RETURN WITH J=0
MOVE T3,P1 ;SET T3=ABSOLUTE ADDRESS OF ERROR WORD
LSH T3,W2PLSH## ;T3=ABSOLUTE PAGE NUMBER OF PAGE CONTAING BAD WORD
MOVEI T2,JOBMAX## ;SCAN TO SEE IF BAD ADDRESS IS IN A UPMP
AUPLOP: HRRZ T1,JBTUPM##(T2) ;T1=PAGE NUMBER OF THE UPMP
CAIE T1,(T3) ;BAD WORD IN THIS UPMP?
SOJG T2,AUPLOP ;NO, SCAN ALL USER PAGE MAP PAGES
JUMPG T2,[MOVN J,T2 ;IF YES, NEGATIVE JOB NUMBER TO J
PJRST CPOPJ1##] ;SKIP RETURN
MOVEI J,1 ;NOW SCAN ALL HIGH/LOW SEGS. STARTING WITH JOB 1
ASNLOP: MOVEI T1,0 ;ASSUME PARITY ERROR IS IN PAGE 0 OF THIS SEGMENT
MOVSI T2,SHRSEG ;SHARABLE SEGMENT BIT
CAILE J,JOBMAX## ;IS THIS A LOW SEGMENT?
TDNE T2,JBTSTS##(J) ;NO--THEN IT IS A SHARABLE HIGH SEG?
SKIPN JBTADR##(J) ;IS THIS JOB OR HIGH SEG IN CORE?
JRST ASNAOJ ;NO, LOOK AT THE NEXT SEGMENT
LDB T2,JBYHSA## ;ASSUME ITS A HIGH SEG, GET STARTING PAGE NO.
CAIG J,JOBMAX## ;IS IT A HIGH SEGMENT?
LDB T2,JBYLSA## ;NO--GET STARTING PAGE NUMBER OF LOW SEGMENT
ASNHGH: CAIN T2,(T3) ;IS THIS PAGE THE SAME PAGE WHICH CONTAINED AN ERROR?
JRST CPOPJ1## ;YES--RETURN SEGMENT NO. IN J
HRRZ T2,PAGTAB(T2) ;T2=PAGE NO. OF NEXT PAGE IN THIS SEGMENT
SKIPE T2 ;IS IT THE LAST PAGE IN THIS SEGMENT?
AOJA T1,ASNHGH ;NO, LOOK AT ALL THE PAGES IN THIS SEGMENT
ASNAOJ: CAIG J,JBTMAX## ;LOOKED AT ALL SEGMENTS?
AOJA J,ASNLOP ;NO, LOOK AT NEXT SEGMENT
POPJ P, ;NOT IN MONITOR OR ANY JOB
;SUBROUTINE TO FIX CORE ALLOCATION TABLES AFTER PAGES HAVE BEEN
; MARKED OUT IN NXMTAB DUE TO PARITY ERRORS OR NXM'S
;CALLING SEQUENCE:
; MAKE NXMTAB REFLECT CURRENT STATE OF MEMORY, GIVE BACK CORE
; BELONGING TO ALL SEGMENTS WHICH OVERLAP NXM, AND
; PUSHJ P,CPLNXF ;FIX UP RELEVANT TABLES AND VARIABLES
;RETURNS CPOPJ IF NEW VALUE OF CORMAX .LE. OLD VALUE OF CORMAX (SOME
; JOB MAY BE TOO BIG TO SWAP IN), CPOPJ1 IF ALL IS OK.
;MUST HAVE THE MM RESOURCE-CALLER'S RESPONSIBILITY
CPINXF::PUSHJ P,SAVE2## ;SAVE WORKING ACS
SETZB T1,T2 ;INITIALIZE INDEXS INTO PAGTAB AND NXMTAB
MOVSI T3,400000 ;FIRST BIT TO LOOK AT IN NXMTAB
LDB T4,[POINT 14,MEMSIZ##,26]
MOVSI P1,NXMBIT ;LOOK FOR NON-EXISTANT PAGES
HRROI P2,MPGSIZ## ;DECREASE MAXMAX BY 1 PAGE FOR EACH NON-EXISTANT PAGE SEEN
CPINX1: TDNN P1,PAGTAB(T1) ;PAGE ALREADY MARKED AS NON-EXISTANT?
TDNN T3,NXMTAB##(T2) ;NO, IS IT NON-EXISTANT NOW?
JRST CPINX2 ;NO, FORGE AHEAD
SKIPL PAGTAB(T1) ;IS THIS NON-EXISTANT PAGE ON THE FREE CORE LIST?
STOPCD .,STOP,NPN, ;++NON-EXISTANT PAGE NOT FREE
ADDM P2,MAXMAX## ;DECREASE MAXMAX BY 1 PAGE
HLLM P1,PAGTAB(T1) ;AND MARK THIS PAGE AS NOW NON-EXISTANT
CPINX2: ADDI T1,1 ;NEXT PAGE
ROT T3,-1 ;NEXT BIT POSITION IN NXMTAB
SKIPG T3 ;CROSSED A WORD BOUNDARY?
ADDI T2,1 ;YES, BUMP TO NEXT WORD IN NXMTAB
SOJG T4,CPINX1 ;LOOP OVER ALL PAGES
CPINX3: MOVE T1,PAGPTR## ;POINTER TO THE FREE CORE LIST
JUMPE T1,CPINX5 ;JUMP IF THERE ARE CURRENTLY NO PAGES ON THE FREE LIST
TDNN P1,PAGTAB(T1) ;IS THIS PAGE NOW NON-EXISTANT?
JRST CPINX5 ;NO
MOVE T2,PAGTAB(T1) ;YES, LINK FREE CORE LIST AROUND THE PAGE
HRRZM T2,PAGPTR## ;STORE NEW FIRST PAGE ON THE FREE CORE LIST
SOS CORTAL## ;DECREMENT COUNT OF POTENTIALLY FREE PAGES
SOS BIGHOL## ;DECREMENT COUNT OF FREE PAGES
JRST CPINX3 ;CONTINUE TO LOOK AT PAGES AT THE BEGINNING
; OF THE FREE CORE LIST
CPINX4: MOVE T1,T2 ;CURRENT INDEX INTO PAGTAB
CPINX5: HRRZ T2,PAGTAB(T1) ;NEXT PAGE IN PAGTAB
JUMPE T2,CPINX6 ;JUMP IF THIS IS THE END OF THE FREE CORE LIST
TDNN P1,PAGTAB(T2) ;IS THIS PAGE NOW NON-EXISTANT?
JRST CPINX4 ;NO
HRRZ T2,PAGTAB(T2) ;YES, LINK THE FREE CORE LIST AROUND IT
HRRM T2,PAGTAB(T1) ; ..
SOS CORTAL## ;DECREMENT THE COUNT OF POTENTIALLY FREE PAGES
SOS BIGHOL## ;AND THE COUNT OF FREE PAGES
JRST CPINX5 ;LOOP OVER THE ENTIRE FREE CORE LIST
CPINX6: MOVEI T1,0 ;INITIALIZE COUNT OF EXISTANT UNLOCKED PAGES
MOVE T2,MEMSIZ## ;PREVIOUS HIGHEST ADDRESS + 1
SUB T2,SYSSIZ## ;RANGE OF USERS CORE
LSH T2,W2PLSH## ;NUMBER OF PAGES FROM TOP OF THE MONITOR
; TO THE PREVIOUS TOP OF MEMORY
MOVE T3,SYSSIZ## ;WHERE TO START LOOKING FOR UNLOCKED EXISTANT PAGES
LSH T3,W2PLSH## ;PAGE NUMBER TO START AT
CPINX7: MOVE P1,PAGTAB(T3) ;PAGE DESCRIPTOR BITS FROM PAGTAB
TLNE P1,LKBITS-MONTRB;IS THIS PAGE LOCKED OR NON-EXISTANT?
JRST CPINX8 ;YES, DON'T CONSIDER IT IN COMPUTING NEW CORMAX
MOVEI T4,1(T3) ;HIGHEST EXISTANT PAGE + 1 THAT WAS SEEN
TLNN P1,MONTRB ;IS THIS A MONITOR PAGE?
ADDI T1,PAGSIZ## ;NO, INCREASE NEW CORMAX BY ONE PAGE
CPINX8: ADDI T3,1 ;NEXT PAGE IN PAGTAB
SOJG T2,CPINX7 ;LOOP OVER ALL PAGES
MOVEI T2,PAGTAB-1(T4) ;BYTE POINTER TO HIGHEST PAGE
HRRM T2,CORLST## ;STORE THAT FOR CHKTAL
LSH T4,P2WLSH## ;HIGHEST EXISTANT ADDRESS + 1
MOVEM T4,MEMSIZ## ;STORE THAT AS THE SIZE OF MEMORY
MOVE T2,MAXMAX## ;MAXIMUM CORMAX
SUBI T2,NWMCP ;FUNNY SPACE
CAMLE T1,T2 ;ROOM FOR FUNNY PAGES?
MOVE T1,T2 ;NO, MAKE ROOM
CAML T1,CORMAX## ;NEW CORMAX LESS THAN THE OLD CORMAX?
AOSA (P) ;NO, INDICATE ALL JOBS CAN STILL RUN
MOVEM T1,CORMAX## ;YES, STORE NEW VALUE OF CORMAX AND GIVE
; A NON-SKIP RETURN TO INDICATE THAT SOME
; JOBS MAY BE TOO LARGE TO BE SWAPPED IN
POPJ P, ;RETURN
SUBTTL ERROR REPORTING FOR CHANNEL ERRORS
IFN FTKI10!FTKL10,<
;SUBROUTINE TO STORE CHANNEL DATA ON ALL HARD AND SOFT ERRORS
;CALL: MOVE F,DEVICE DATA BLOCK ADR
; MOVE U,UNIT DATA BLOCK ADR
; MOVE P1,CHANNEL DATA BLOCK ADDRESS(CHN'N'CB)
; MOVE T1,ADDRESS OF FIRST CCW IN CCW LIST
; PUSHJ P,CHNMPE OR CHNNXM (MEMORY PARITY OR NXM)
; RETURN WILL ALL REGISTERS PRESERVED EXCEPT T1-T4
;SUBROUTINE FOR MEMORY PARITY
CHNMPE::AOS .CHMPE(P1) ;INCREMENT NO. OF MEM PARITY ERRORS
PUSHJ P,SAVE4## ;SAVE P REGISTERS
SETO P4, ;INDICATE PARITY ERROR
JRST CHNCOM ;JOIN COMMON CODE
;SUBROUTINE FOR NXM
CHNNXM::AOS .CHNXM(P1) ;INCREMENT NO. OF NXMS
PUSHJ P,SAVE4## ;SAVE P REGISTERS
SETZ P4, ;INDICATE NXM ERROR
CHNCOM: SETOM .CPCHE## ;FLAG CHANNEL ERROR CODE IS RUNNING
HRRM U,.CHLUE(P1) ;SAVE UNIT DATA BLOCK ADR
HRRM F,.CHLDE(P1) ;SAVE DEVICE DATA BLOCK ADR
PUSH P,U ;SAVE U
HRRZ U,.CPCTN ;GET CPU'S CTY LINE NUMBER
HRRZ U,LINTAB##(U) ;GET CTY'S LDB
PUSHJ P,CHNCCW ;COLLECT CCW DATA
SKIPE P4 ;IS THIS A NXM ERROR?
PUSHJ P,CHNDAT ;NO--COLLECT DATA WORDS ALSO
MOVEI T1,SDELIM ;GET ADRESS OF TEXT
PUSHJ P,CONMES## ;PRINT START DELIMITER
MOVE T2,.CPLOG## ;GET THIS CPU'S NAME
PUSHJ P,PRNAME ;PRINT IT
SKIPE P4 ;NXM ERROR?
SKIPA T1,[[ASCIZ / channel memory parity error on /]] ;NO--PARITY ERROR
MOVEI T1,[ASCIZ / channel non-existent memory error on /] ; YES--NXM
PUSHJ P,CONMES## ;PRINT ERROR TYPE
PUSHJ P,DAYTIM## ;APPEND DATE AND TIME
MOVEI T1,[ASCIZ /Device in use is /] ;GET TEXT
PUSHJ P,CONMES## ;PRINT DEVICE PREFIX MESSAGE
MOVE T2,DEVMOD(F) ;GET DEVICES CHARACTERISTICS
HRR T2,.CHLUE(P1) ;UDB OF DEVICE WHERE ERROR HAPPENED
TLNE T2,DVDSK ;IS THIS A DISK?
SKIPA T2,(T2) ;YES--GET NAME FROM UDB
MOVE T2,DEVNAM(F) ;NO--GET DEVICE NAME FROM DDB
PUSHJ P,PRNAME ;APPEND IT
MOVEI T1,[ASCIZ /
Channel type is /] ;GET TEXT
PUSHJ P,CONMES## ;PRINT CHANNEL TYPE PREFIX MESSAGE
MOVE T2,CHB22B##(P1) ;GET CHANNEL TYPE BITS
TLNN T2,CP.22B ;22-BIT CHANNEL?
SKIPA T1,[[ASCIZ /DF10/]] ;NO--DEFINITELY A DF10
MOVEI T1,[ASCIZ /DF10-C/] ;YES--POSSIBLY A DF10-C
TLNE T2,CP.DX1 ;IS IT A DX10?
MOVEI T1,[ASCIZ /DX10/] ;YES--GET ITS TEXT
TLNE T2,CP.RH2 ;IS IT AN RH20?
MOVEI T1,[ASCIZ /RH20/] ;YES--GET ITS TEXT
PUSHJ P,CONMES## ;APPEND CHANNEL TYPE
MOVEI T1,[ASCIZ /
Termination channel program address = /] ;GET TEXT
PUSHJ P,CONMES## ;PRINT TERM. CCW ADDRESS MESSAGE
HLRZ T1,.CHFCW(P1) ;GET LH TERMINATION CCW
SKIPGE CHB22B##(P1) ;IS THIS A 22-BIT CHANNEL?
LSH T1,-4 ;YES--THEN ONLY 14 BITS ARE CCW ADDRESS
PUSHJ P,OCTPNT ;PRINT IT
MOVEI T1,[ASCIZ /
Termination data transfer address = /] ;GET TEXT
PUSHJ P,CONMES## ;PRINT TERM. DATA ADDRESS MESSAGE
MOVE T1,.CHFCW(P1) ;GET RH TERMINATION CCW
SKIPGE CHB22B##(P1) ;IS THIS A 22-BIT CHANNEL?
TLZA T1,777760 ;YES--GET JUST DATA ADDRESS (22 BITS)
TLZ T1,-1 ;NO--GET JUST DATA ADDRESS (18 BITS)
PUSHJ P,PRT22A ;PRINT IT
MOVEI T1,[ASCIZ /
Last three channel commands executed are:
/]
PUSHJ P,CONMES## ;PRINT THIS
MOVE T1,.CHCW0(P1) ;ARE ALL CCW'S ZERO?
IOR T1,.CHCW1(P1) ;...
IOR T1,.CHCW2(P1) ;...
SKIPE T1 ;...
JRST CHNCO1 ;NO--GO PRINT THEM OUT
PUSHJ P,PR3SPC## ;YES--INDENT
MOVEI T1,[ASCIZ /** Indeterminate **
/]
PUSHJ P,CONMES## ;TELL THEM WE DON'T KNOW
JRST CHNCO3 ;CONTINUE
CHNCO1: MOVSI P2,-3 ;FORM AOBJN POINTER
HRRI P2,.CHCW2(P1) ; TO SAVED CCW'S
CHNCO2: PUSHJ P,PR3SPC## ;INDENT
MOVE T1,(P2) ;PICK UP CCW
PUSHJ P,HWDPNT ;PRINT IT
PUSHJ P,CRLF## ;PRINT CRLF
AOBJN P2,CHNCO2 ;LOOP IF MORE
CHNCO3: MOVEI T1,EDELIM ;GET ENDING DELIMITER
PUSHJ P,CONMES## ;PRINT IT
POP P,U ;RESTORE U
SETZM .CPCHE## ;CLEAR CHANNEL ERROR IN PROGRESS FLAG
MOVEI T1,.ERCPE ;CHANNEL ERROR CODE
HRL T1,P1 ;GET CDB ADDRESS
PUSH P,J ;SAVE J
PUSHJ P,DAEEIM## ;POKE DAEMON
POP P,J ;RESTORE J
POPJ P, ;RETURN
;ROUTINE TO STORE CCW DATA FOR CHANNEL ERRORS
CHNCCW: MOVE T3,CHB22B##(P1) ;PICK UP CHANNEL TYPE BITS
MOVE T2,0(T1) ;GET FIRST CCW IN LIST
MOVEM T2,.CHICW(P1) ;SAVE IN CDB FOR F.S.
TLNN T3,CP.RH2## ;IS THIS AN RH20?
JRST CHNCC1 ;NO--PROCEED
HRRZ T2,1(T1) ;YES--GET LAST CCW ADDR + 1
MOVE P3,2(T1) ;GET TERMINATION CCW
MOVEM P3,.CHFCW(P1) ;SAVE IN CDB FOR F.S.
JRST CHNCC4 ;CONTINUE
CHNCC1: TLNN T3,CP.DX1## ;IS THIS A DX10?
JRST CHNCC2 ;NO--PROCEED
DPB P2,[POINT 14,P3,13] ;YES--COMBINE IN TERM. CHANNEL PROGRAM COUNTER
JRST CHNCC3 ;CONTINUE
CHNCC2: MOVE P3,1(T1) ;GET TERMINATION CCW FOR DF10/DF10-C
CHNCC3: MOVEM P3,.CHFCW(P1) ;SAVE IN CDB FOR F.S.
HLRZ T2,P3 ;GET ADDRESS OF LAST CCW
TLNE T3,CP.22B## ;IS THIS A 22-BIT CHANNEL?
LSH T2,-4 ;YES--THEN ONLY 14 BITS ARE CCW ADDRESS
CHNCC4: TLNE T3,CP.RH2## ;IS THIS AN RH20?
SOS T2 ;BACK UP LAST CCW ADDRESS BY 1
MOVE P2,T2 ;SAVE REAL FINAL CCW ADDRESS HERE
CAIL T2,2 ;IS FIRST SOURCE ABOVE LOC 0?
CAML T2,MEMSIZ## ;YES, IS LAST SOURCE ADR IN BOUNDS?
JRST CHNCC6 ;NO--JUNK DATA, DON'T ATTEMPT RETRIEVAL
CHNCC5: MOVE P3,.CHCW0(P1) ;PUSH EVERYBODY DOWN ONE
EXCH P3,.CHCW1(P1) ;...
MOVEM P3,.CHCW2(P1) ;...
MOVE P3,(T1) ;GET THIS CCW
MOVEM P3,.CHCW0(P1) ; AND SAVE AS LAST CCW
CAMN P2,T1 ;DOES ITS ADDRESS MATCH THE CHANNEL TERM ADDR?
JRST CHNCC7 ;YES--WE'RE DONE, STOP CHASING LIST
TLNE P3,577777 ;IS CCW A DATA TRANSFER?
AOJA T1,CHNCC5 ;YES--BUMP CCW ADDRESS AND GO AROUND AGAIN
JUMPE P3,CHNCC6 ;NO--IF IT'S A HALT, WE'VE RUN OUT UNEXPECTEDLY
TLNE T3,CP.DX1## ;IS THIS A DX10?
TLNE P3,200000 ;YES--IS THIS A DX10 DEVICE COMMAND CCW?
SKIPA ;NO--NOT DX10 OR IT'S A DX10 JUMP
AOJA T1,CHNCC5 ;YES--BUMP CCW ADDRESS AND GO AROUND AGAIN
MOVE T1,(T1) ;IT'S A JUMP, GET NEXT CCW ADDRESS
TLNE T3,CP.22B## ;IS THIS A 22-BIT CHANNEL?
TLZA T1,777760 ;YES--GET JUST ADDRESS (22-BITS)
TLZ T1,-1 ;NO--GET JUST ADDRESS (18-BITS)
JRST CHNCC5 ; AND GO AROUND AGAIN
CHNCC6: SETZM .CHCW2(P1) ;ZERO THE CCW LOCATIONS
SETZM .CHCW1(P1) ;...
SETZM .CHCW0(P1) ;...
CHNCC7: MOVE T2,CHNTCW##(P1) ;GET EXPECTED TERMINATION CCW
MOVEM T2,.CHTCW(P1) ;SAVE FOR F.S.
POPJ P, ;RETURN
;HERE TO COLLECT RELEVANT DATA WORDS ON PARITY ERROR
CHNDAT: MOVE T4,.CHFCW(P1) ;GET TERMINATION CCW
SKIPGE CHB22B##(P1) ;IS THIS A 22-BIT CHANNEL?
TLZA T4,777760 ;YES--GET JUST ADDRESS (22-BITS)
TLZ T4,-1 ;NO--GET JUST ADDRESS (18-BITS)
CAIL T4,2 ;IS LAST DATA ADR ABOVE 0?
CAML T4,MEMSIZ## ;YES, IS IT IN BOUNDS?
JRST CHNDA2 ;NO--JUNK DATA, DON'T ATTEMPT RETRIEVAL
PUSHJ P,MAPLOC## ;GET EVA SLOT
MOVEI T3,.ERPIL(T3) ;FORM EVA PAGE NUMBER
SUBI T4,2 ;BACK UP STARTING ADDRESS BY TWO
MOVEI P2,.CHDW2(P1) ;PLACE TO STORE DATA WORDS
HRLI P2,-3 ;MAKE AOBJN PNTR
CHNDA1: LDB P3,[POINT 13,T4,26] ;GET PAGE NUMBER
IORI P3,PM.ACC!PM.WRT ;SET ACCESS BITS
DPB P3,T1 ;MAP THIS PAGE
CLRPGT (0) ;CLEAR PAGING MEMORY
DPB T4,[POINT 9,T3,35] ;SET LINE # IN PAGE
MOVE P3,(T3) ;FETCH DATA WORD
MOVEM P3,(P2) ;STASH IN CDB
ADDI T4,1 ;ADVANCE TO NEXT LOC
AOBJN P2,CHNDA1 ;LOOP TILL DONE
MOVEI T2,↑D50 ;WAIT FOR ANY PARITY INTERRUPTS
SOJG T2,. ;TO HAPPEN (IF ANY)
POPJ P, ;RETURN
CHNDA2: SETZM .CHDW0(P1) ;ZERO THE DATA LOCATIONS
SETZM .CHDW1(P1) ;...
SETZM .CHDW2(P1) ;...
POPJ P, ;RETURN
>;END IFN FTKI10!FTKL10
IFN FTKS10,<
CHNMPE::
CHNNXM::POPJ P,
>;END IFN FTKS10
SUBTTL STOPCODE PROCESSING
;ROUTINE TO RECOVER/RELOAD AFTER AN INTERNAL
; SYSTEM ERROR. CALLED ONLY BY STOPCD MACRO
; (SEE S.MAC) WITH:
; PUSHJ P,DIE
; CAI TYPE,NAME (CONT)
;
; -OR-
;
; PUSHJ P,DIE
; CAIA TYPE,NAME (17)
; JRST CONT
;
DIE:: AOSE .CPDWD## ;INTERLOCK STOPCD CODE
STOPCD .,HALT,REH, ;++RECURSION IN ERROR HANDLER
CONI PI,.CPCPI## ;SAVE STATE OF MACHINE
CONO PI,PI.TFP+177 ; ..
JSR .CPSVA## ;SAVE ALL AC SETS
MOVE T1,.UPMP+.UPMUO
MOVEM T1,.CPTRP##
MOVE M,@(P) ;M=FLAG WORD
POP P,T1 ;GET PC OF STOPCD
MOVEM T1,%SYSPC## ;STORE IN TRADITIONAL WORD
MOVEM T1,.CPSUP## ; AND IN CDB
MOVE P,.CPEPD## ;SETUP PDL FOR THIS CPU
PUSHJ P,RCDSTB## ;READ CPU AND DEVICE STATUS BLOCKS
IFN FTKL10,<
PUSHJ P,CSDMP## ;MAKE SURE IT'S ALL IN CORE
PUSHJ P,SKPMRN## ;SKIP IF MASTER -11 IS RUNNING
STOPCD .,HALT,MNR, ;++MASTER -11 NOT RUNNING
PUSHJ P,DIE1 ;PROCESS STORAGE
JRST RESRET ;RESTORE & RETURN
DIE1: PUSHJ P,SVPPC## ;SAVE PROTOCOL
>
IFN FTKS10,<
PUSHJ P,DISKAL## ;DISABLE KEEP ALIVE FUNCTION
>
IFN FTMP,<
DIE2: AOSN DIELOK## ;GET DIE INTERLOCK
JRST DIE3 ;GOT IT, CONTINUE
SKIPN CRSHWD## ;RELOADING?
JRST DIE2 ;NO, LOOP FOR INTERLOCK
PJRST REBOOT## ;YES
DIE3:
IFN FTKI10,<
CONI PAG,INODIE## ;MAKE ME THE OWNER OF THE INTERLOCK
>
IFN FTKL10,<
APRID INODIE## ;MAKE ME THE OWNER OF THE INTERLOCK
>
>
PUSH P,.CPTOA## ;SAVE ADDRESS OF TYPEOUT ROUTINE
MOVEI T1,CTYWAT## ;REPLACE IT WITH ONE THAT DOESN'T USE PI'S
MOVEM T1,.CPTOA## ;MODIFY SCNSER
HRRZ U,.CPCTN## ;POINT TO CONSOLE TERMINAL FOR THIS CPU
MOVEI T2,↑D10 ;SEND 10 BELLS
PUSHJ P,BELLS ;..
PUSHJ P,INLMES## ;PRINT MESSAGE
ASCIZ /
?/
MOVE T2,.CPLOG##
PUSHJ P,PRNAME
PUSHJ P,INLMES##
ASCIZ / monitor error. Stopcode name is /
HRLZ T2,M ;GET CODE
TLNE M,(Z 10,0) ;LONG FORM
HRLZ T2,0(M) ;YES, GET CODE
HLLM T2,%SYSPC## ;SAVE NAME
HLLM T2,.CPSNM##
PUSHJ P,PRNAME ;PRINT IT OUT
PUSHJ P,CRLF## ;ADD A CRLF
MOVE J,.CPJOB##
MOVEI S,PI.IPA ;GET PI ON MASK
AND S,.CPCPI## ;MASK OUT ALL ELSE
SKIPN S ;INTERRUPT LEVEL?
PUSHJ P,WHATJB ;NO--GIVE INFO
TLZ F,-1 ;CLEAR LH BITS
PUSHJ P,CHKDDB ;MAKE SURE THAT F POINTS TO A DDB
JRST NODDB ;IT DOESN'T, DON'T PRINT THE INFORMATION
LDB T1,PJOBN## ;GET JOB #
CAILE T1,JOBMAX## ;TOO BIG?
JRST NODDB ;YES--NOT A DDB
JUMPE T1,NODDB ;WANT REAL JOB #
PUSHJ P,INLMES##
ASCIZ /File /
PUSHJ P,PRTDDB## ;PRINT DDB STUFF
PUSHJ P,CRLF## ;ADD CRLF
JUMPE S,NODDB ;UUO LEVEL-SAID THIS
LDB J,PJOBN## ;GET JOB #
PUSHJ P,WHATJB ;PRINT IT
NODDB: TLZN M,(Z 10,0) ;ADDITIONAL INFORMATION
JRST NOTYPE ;NO, PRESS ON
HLRZ T1,0(M) ;TYPE OUT ROUTINE
HRR M,0(M) ;PUT STOPCD NAME INTO RH OF M
JUMPE T1,NOTYPE ;REALLY SHOULD BE ONE
PUSHJ P,0(T1) ;CALL IT
PUSHJ P,CRLF## ;TERMINATE LINE
NOTYPE: SKIPGE DEBUGF## ;WANT DDT?
JRST DIEADP ;YES
PUSHJ P,TYPCSB## ;TYPE CPU STATUS BLOCK INFO ON THE CTY
LDB T1,PUUOAC## ;GET ERROR TYPE
CAIL T1,1 ;BE SURE IT'S IN RANGE
CAILE T1,4 ;JUST SUPER CAUTIOUS
JRST RELOAD ;BAD. DON'T MAKE IT WORSE
JRST @[EXP RELOAD,ZAPJOB,BUGCHK,CPUSTP]-1(T1)
;HERE ON A DEBUG STOPCD
BUGCHK: PUSHJ P,STCLIM ;EXCEED STOPCD LIMIT?
JRST SCLEXC ;YES
MOVSI T1,(DF.RDC) ;DO WE WANT TO
TDNE T1,DEBUGF## ; RELOAD?
JRST RELOAD ;YES--GO RELOAD
AOS %SYNDS## ;COUNT BUG
AOS .CPSND##
IFN FTMBTS,<
MOVSI T1,(DF.DDC) ;WANT TO DUMP ON
TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD?
PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN
>
PUSHJ P,INLMES## ;NO--CONTINUE
ASCIZ /[Continuing system]
/
DIEADP: MOVE T3,.CPACA## ;GET ADDRESS OF SAVED AC BLOCK
MOVE T1,P(T3) ;GET OLD STACK POINTER
LDB T2,[POINT 4,M,17] ;GET RETURN TYPE
XCT CONTAB(T2) ;FIX UP PDP
MOVEM T1,P(T3) ;SAVE BACK
JRST DIERS0 ;RESTORE STATE OF MACHINE
;HERE ON A JOB ERROR STOPCD
ZAPJOB: PUSHJ P,STCLIM ;STOPCD LIMIT EXCEEDED?
JRST SCLEXC ;YES
MOVSI T1,(DF.RJE) ;IS RELOAD ON JOB ERROR
TDNN T1,DEBUGF## ; REQUESTED?
SKIPE S ; OR PI LEVEL?
JRST RELOAD ;YES--GO RELOAD
SKIPE .UPMP+.UPJOB ; CAN'T STOP THE NULL JOB.
SKIPE .CPISF## ;IN SCHEDULER CONTEXT?
JRST RELOAD ;YES, CAN'T REALLY STOP A JOB
AOS %SYNJS## ;COUNT BUG
AOS .CPSNJ##
IFN FTMBTS,<
MOVSI T1,(DF.DJE) ;WANT TO DUMP ON
TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD?
PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN
>
PUSHJ P,INLMES## ;NO--ZAP JOB
ASCIZ /[Aborting job]
/
PUSHJ P,GIVLOK## ;GIVE BACK LOCKS THIS CPU OWNS
MOVE T2,.CPACA## ;GET ADDRESS OF AC BLOCK
MOVEI T1,BUGSTP ;ADJUST SAVED STACK
MOVE T2,P(T2) ;SO THIS JOB GETS
MOVEM T1,(T2) ;KILLED
JRST DIERS0 ;RESTORE STATE OF SYSTEM
;HERE ON A CPU STOPCD
IFN FTMP,<
CPUSTP: PUSHJ P,STCLIM ;STOPCD LIMIT EXCEEDED?
JRST SCLEXC ;YES
MOVSI T2,(DF.CP1) ;BIT FORCING CPU STOPCDS TO CAUSE RELOAD
PUSHJ P,LSTCPU## ;LAST OR ONLY CPU RUNNING IN SYSTEM?
TDNE T2,DEBUGF## ;NO, WANT TO RELOAD ON CPU STOPCDS?
JRST RELOAD ;YES, RELOAD THE SYSTEM
AOS .CPSNC## ;COUNT BUG
IFN FTMBTS,<
MOVSI T1,(DF.DCP) ;WANT TO DUMP ON
TDNN T1,DEBUGF## ; THIS TYPE OF STOPCD?
PUSHJ P,CRSDMP ;DUMP SYSTEM AND RETURN
>
PUSHJ P,INLMES## ;TELL OF OUR ACTION
ASCIZ /[Stopping CPU]
/
PUSHJ P,KILUSR ;INSURE THAT THE CURRENT JOB IS STOPPED
; TO AVOID A REPEAT OF THE STOPCD IF
; HE STARTS TO RUN ON ANOTHER CPU
POP P,.CPTOA## ;RESTORE SCNSER TYPOUT ADDRESS
SETOM .CPOK## ;INSURE THAT BECOM0 WILL BE CALLED
SETOM INODIE## ;NO LONGER INTERLOCK OWNER
SETOM DIELOK## ;NO LONGER HAVE INTERLOCK
MOVEI T1,SR.DIE ;TELL CP1CRS THAT WE WANT THE OPERATOR
IORM T1,.CPSBR## ; TO MANUALLY RESTART THIS CPU
SKPCPU (1) ;IF ON THE BOOT CPU, WAIT FOR SOMEONE
JRST .-1 ; TO ASSUME THE ROLE
PJRST REBOOT## ;SAVE STATE OF THE MACHINE
>
;HERE IF WE EXCEEDED ONE OF THE STOPCD-PER-UNIT-TIME LIMITS TO RELOAD
;THE SYSTEM.
SCLEXC: PUSHJ P,INLMES## ;TELL WHAT HAPPENED
ASCIZ/?Stopcode limit exceeded
/
;HERE TO RELOAD THE SYSTEM
IFE FTMP,<
CPUSTP:
>
RELOAD: HRRZM M,CRSWHY## ;SAVE REASON FOR ONCE ATER RELOAD
PUSHJ P,INLMES##
ASCIZ /Reload monitor
/
MOVEI T2,↑D20 ;20 BELLS
PUSHJ P,BELLS ;..
MOVE P,.CPACA## ;GET ADDRESS OF AC BLOCK
MOVE P,P(P) ;RESTORE PDP
POP P,CRSHWD## ;SAVE PC
SOS CRSHWD## ;FOR SYSTAT/X
PJRST REBOOT## ;YES, RELOAD NOW
;HERE TO RESTORE THE STATE OF THE MACHINE
DIERS0: POP P,.CPTOA## ;RESTORE SCNSER
IFN FTKL10,<
POPJ P, ;RETURN ON A KL
>
RESRET:
IFN FTDAEM,<
PUSHJ P,DAEEST## ;TELL DAEMON OF STOPCD
>
MOVEI T1,177 ;ALL PI BITS
AND T1,.CPCPI## ;TURN ON ONLY
IORI T1,PI.TNP ;ONES WHICH WERE ON
MOVEM T1,.CPCPI## ;SAVE FOR CONO
HRLZ 17,.CPACA## ;WHERE TO RESTORE THE AC'S FROM
BLT 17,17 ;RESTORE THEM ALL
IFN FTMP,<
SETOM INODIE## ;NO LONGER THE OWNER OF THE INTERLOCK
SETOM DIELOK## ;OR HAVE THE INTERLOCK
>
CONO PI,@.CPCPI## ;TURN ON PI SYSTEM
SKIPGE DEBUGF## ;WANT DDT?
XCT SYSDDT## ;YES
DIECON::SETOM .CPDWD## ;ALLOW STOPCD'S
IFN FTKS10,<
PUSHJ P,ENAKAL## ;ENABLE KEEP ALIVE FUNCTION
>
POPJ P,
;HERE TO STOP AN ILL FATED USER
BUGSTP: MOVE J,.CPJOB## ;JOB NUMBER
PUSHJ P,ZAPUSR ;GIVE UP LOCKS AND DEVICES
JSP T1,ERRPTU ;PRINT MESSAGE
ASCIZ /Monitor error/
PJRST UUOPCP ;PRINT SOME PC'S
;ROUTINE TO KILL THE CURRENT JOB RUNNING ON THIS CPU TO MAKE SURE
;THAT IT DOESN'T CONTINUE TO CAUSE THE SAME CRASH OVER AND OVER AGAIN.
;MUST NOT BE CALLED WITH A UUO LEVEL STACK SINCE ZAPPGM WILL GIVE
;BACK THE PAGE MAP.
KILUSR: PUSHJ P,GIVLOK## ;RETURN INTERLOCKS OWNED BY THIS CPU
SKIPN J,.CPJOB## ;ANY JOB RUNNING ON THIS CPU?
POPJ P, ;NO, JUST RETURN
PUSHJ P,ZAPUSR ;GIVE UP LOCKS AND DEVICES
PUSH P,JBTSTS##(J) ;SAVE CURRENT STATE OF JBTSTS
MOVSI T1,JLOG ;CLEAR JLOG TEMPORARILY SO THAT
ANDCAM T1,JBTSTS##(J) ; ZAPPGM WILL GIVE BACK ALL OF THE
ANDM T1,0(P) ; USER'S CORE. I KNOW IT'S UGLY BUT...
PUSHJ P,ZAPPGM## ;GIVE BACK ALL OF HIS CORE
POP P,T1 ;GET BACK STATE OF JLOG BIT
IORM T1,JBTSTS##(J) ;SET IT IF IT WAS SET BEFORE
POPJ P, ;RETURN
;SUBROUTINE TO SEND C(T2) BELLS
;CLOBBERS T1, T2, T3, T4
BELLS:: MOVEI T3,"G"-100 ;BELL
BELOOP: PUSHJ P,COMTYO## ;DING
MOVEI T1,200000
LSH T1,-2*FTKL10-FTKI10
SOJG T1,.
SOJG T2,BELOOP ;LOOP FOR ALL
POPJ P, ;RETURN
;ROUTINE TO CHECK A DDB ADDRESS BEFORE USING IT TO TYPE FILE INFORMATION
;DURING DIE PROCESSING.
;CALL: MOVEI F,ADDRESS
; PUSHJ P,CHKDDB
; RETURN HERE IF ADDRESS IS ILLEGAL FOR SOME REASON
; RETURN HERE IF ADDRESS IS OK
CHKDDB: CAMGE F,SYSSIZ## ;LARGER THAN THE LOW SEG?
CAIG F,1000 ;OR TOO SMALL?
CAIA ;YES, MAY STILL BE IN FUNNY SPACE
JRST CPOPJ1## ;GIVE SKIP RETURN
CAIL F,.FPMC ;LEGAL ADDRESS IN
CAIL F,.FPMC+NWMCP ; FUNNY SPACE?
POPJ P, ;NO, BAD DDB ADDRESS
MAP T1,(F) ;MAP THE ADDRESS
PUSHJ P,FLTCHK## ;WILL REFERENCE FAULT?
POPJ P, ;YES, BAD ADDRESS
MAP T1,DEVSFD##(F) ;LAST ADDRESS IN DDB REFERENCED BY PRTDDB
PJRST FLTCHK## ;CHECK ADDRESS AND RETURN
;ROUTINE TO SEE IF THIS STOPCD HAS CAUSED US TO EXCEED ON OF THE
;STOPCDS-PER-UNIT-TIME LIMITS.
;CALL: PUSHJ P,STCLIM
; RETURN HERE IF A LIMIT HAS BEEN EXCEEDED
; RETURN HERE IF NOT
STCLIM: SKIPGE DEBUGF## ;IF DEBUGGING
JRST CPOPJ1## ;THEN NOSTOPCD LIMITS
MOVSI T1,-SCCTBL## ;BUILD AOBJN POINTER TO TABLE
STCLI1: AOS T2,SCCTAB##(T1) ;INCREMENT NEXT COUNT
HRRZ T3,SCLTAB##(T1) ;GET THE LIMIT
CAIL T2,(T3) ;EXCEED THE LIMIT?
POPJ P, ;YES
AOBJN T1,STCLI1 ;NO, LOOP FOR NEXT
HLRZ T1,SCLTAB##+0 ;GET PERIOD OF LOWEST ENTRY IN TABLE
IMUL T1,TICSEC## ;SETUP CLOCK REQUEST TO DECREMENT THE
HRLI T1,DECSCC ; 1 MINUTE STOPCD COUNT. DECSCC WILL,
MOVEI T2,0 ; IN TURN, PUT IN A CLOCK REQUEST TO DECREMENT
IDPB T1,CLOCK## ; THE NEXT ONE, AND SO ON, UNTIL ALL
IDPB T2,CLOCK## ; LEVELS OF COUNTS HAVE BEEN DECREMENTED.
SETOM CLKNEW## ;I REALIZE THE CLOCK QUEUE HASN'T BEEN
; INTERLOCKED WITH SYSPIF BUT BY THE
; TIME THE FIRST CHARACTER OF THE STOPCD
; MESSAGE HAS TYPED ON THE CTY, ALL OTHER
; CPU'S SHOULD HAVE SEEN DIELOK GO NON-ZERO
JRST CPOPJ1## ;GIVE SKIP RETURN
;ROUTINE TO DECREMENT A STOPCD COUNT AND RESUBMIT A CLOCK QUEUE REQUEST
;FOR THE NEXT HIGHER COUNT, IF ONE EXISTS.
;CALL: MOVEI T1,INDEX INTO SCCTAB
; PUSHJ P,DECSCC
; RETURN HERE ALWAYS
DECSCC::SOSGE SCCTAB##(T1) ;DECREMENT COUNT
SETZM SCCTAB##(T1) ;LEAVE ZERO IF IT WAS ZERO
AOS T1 ;INCREMENT LEVEL
CAIL T1,SCCTBL## ;DONE THE LAST LEVEL?
POPJ P, ;YES, RETURN NOW
MOVE T2,SCLTAB##(T1) ;GET WORD WITH NEW PERIOD
SUB T2,SCLTAB##-1(T1) ;SUBTRACT OLD PERIOD
HLRZS T2 ;KEEP JUST DIFFERENCE IN PERIODS
IMUL T2,TICSEC## ;CONVERT TO TICKS
HRLI T2,DECSCC ;WANT TO COME BACK HERE
SYSPIF ;INTERLOCK THE QUEUE
IDPB T2,CLOCK## ;STORE REQUEST
IDPB T1,CLOCK## ; AND DATA
SETOM CLKNEW## ;FLAG A NEW REQUEST
PJRST ONPOPJ## ;RETURN INTERLOCK AND POPJ
;ROUTINES FOR STOPCODE MACRO TYPE OUT
;ALL ROUTINES WILL HAVE THE FORM DIE???::
;WHERE ??? ARE 3 LETTERS DESCRIPTIVE OF THE ROUTINE
;AN AUTOMATIC CARRIAGE RETURN/LINE FEED IS DONE BY CALLER
;ROUTINE TO TYPE OUT UNINAM(U) DURING STOPCD
DIEUNI::PUSHJ P,INLMES## ;START THE OUTPUT
ASCIZ \Unit = \
MOVE T2,.CPACA## ;GET ADDRESS OF AC SET
MOVE T2,U(T2) ;GET "U" AT CRASH
MOVE T2,UNINAM##(T2) ;GET THE NAME
PJRST PRNAME ;PRINT OUT SIXBIT AND RETURN
IFN FTMBTS,<
;ROUTINE TO CALL BUGDMP TO TAKE A CONTINUABLE STOPCD DUMP
;AND THEN SET DF.RQC IN DEBUGF WHICH WILL CAUSE CRSCPY
;TO BE CALLED BY THE BOOT CPU AT THE NEXT TICK. WE
;CAN'T CALL CRSCPY DIRECTLY BECAUSE THE SCNSER INTERLOCK
;MAY NOT BE FREE.
;ENTER AT FRCCPY TO JUST SET DF.RQC (FROM ADDSDL)
;CALL: PUSHJ P,CRSDMP
; RETURN HERE ALWAYS
CRSDMP: PUSH P,JOBSYM## ;KEEP DAEMON FROM THINKING THIS IS A
SETZM JOBSYM## ;↑↑RELOAD BY ZEROING THE FLAG THAT IT LOOKS AT
PUSHJ P,BUGDMP## ;TAKE DUMP
JFCL ;IGNORE ERROR RETURN
POP P,JOBSYM## ;RESTORE SYMBOL TABLE POINTER
FRCCPY::MOVSI T1,(DF.RQC) ;SET BIT IN DEBUGF WHICH WILL CAUSE
IORM T1,DEBUGF## ; CRSCPY TO BE CALLED AT THE NEXT TICK
POPJ P, ;RETURN
;ROUTINE TO START UP THE CRASH COPY PROGRAM TO COPY
;A DUMP.
;CALL: PUSHJ P,CRSCPY
; RETURN HERE ALWAYS
CRSCPY::SKIPGE DEBUGF## ;DON'T DO ANYTHING
POPJ P, ; IF DEBUGGING
PUSHJ P,FRCSET## ;SETUP TO STORE CHARACTERS IN FRCLIN
MOVE T2,CCPNAM## ;GET NAME OF PROGRAM TO RUN
PUSHJ P,PRNAME ;STORE NAME
PJRST CRLF## ;ADD CRLF AND RETURN
>;END IFN FTMBTS
;CONTINUE TABLE. T1 IS STACK POINTER FOR PROCESS WHICH DID STOPCD.
;CALLED BY XCT CONTAB(CONT)
CONTAB: JFCL ;(0) .
JFCL ;(1) .+1
POP T1,(T1) ;(2) CPOPJ
PUSHJ P,[POP T1,(T1)
AOS (T1)
POPJ P,] ;(3) CPOPJ1
JFCL ;(4)
JFCL ;(5)
JFCL ;(6)
JFCL ;(7)
JFCL ;(10)
JFCL ;(11)
JFCL ;(12)
JFCL ;(13)
JFCL ;(14)
JFCL ;(15)
JFCL ;(16)
AOS (T1) ;(17) SPECIAL RETURN
WHATJB: JUMPLE J,CPOPJ## ;GET JOB NUMBER
CAILE J,JOBMAX## ;RANGE CHECK IT.
POPJ P, ;IGNORE IF FUNNY.
PUSHJ P,INLMES## ;GIVE THE JOB NUMBER
ASCIZ /Job / ; ..
MOVE T1,J ; ..
MOVEM T1,%SYSJN##
MOVEM T1,.CPSJN##
PUSHJ P,RADX10 ;IN DECIMAL
PUSHJ P,INLMES## ;PRINT OUT THE
ASCIZ / on / ; TTY NAME
MOVE T2,@TTYTAB##(J) ;GET TTY NAME
MOVEM T2,%SYSTN##
MOVEM T2,.CPSTN##
PUSHJ P,PRNAME ; AND PRINT IT.
PUSHJ P,INLMES## ;PRINT OUT
ASCIZ / running / ; THE CUSP NAME
MOVE T2,JBTPRG##(J) ; SO OPERATOR
MOVEM T2,%SYSPN##
MOVEM T2,.CPSPN##
PUSHJ P,PRNAME ; CAN FIND HIS JOBS
PUSHJ P,INLMES##
ASCIZ/ User /
MOVE T2,JBTPPN##(J) ;GET USER'S PPN
MOVEM T2,%SYSPP## ;AND SAVE FOR DAEMON
MOVEM T2,.CPSPP##
PUSHJ P,PRTPPN## ;PRINT PPN
JUMPN S,CRLF##
PUSHJ P,INLMES## ;NEW LINE
ASCIZ /
UUO is /
MOVE T1,.CPTRP## ;PICK UP UUO
MOVEM T1,%SYSUU##
MOVEM T1,.CPSUU##
PUSHJ P,PRTDI8 ;PRINT IN OCTAL
MOVE T2,.JDAT+JOBPD1## ;GET PC FROM PUSH DOWN LIST
MOVEM T2,%SYSUP##
MOVEM T2,.CPSUP##
PUSHJ P,PCP ;LIST THE LOCATION
PJRST CRLF## ;RETURN ON A NEW LINE
SUBTTL UUO LEVEL ERROR ROUTINES
;INPUT UUO FOR OUTPUT DEVICE
;CALLED AT UUO LEVEL ONLY
ILLINP::JSP T1,ERRPTU
ASCIZ /output /
PUSHJ P,ERNAM ;PRINT "DEVICE XXX"
JSP T1,UUOMES ;PRINT MESSAGE,UUOPC,STOP JOB
ASCIZ / cannot do input/
;OUTPUT UUO FOR INPUT DEVICE
;CALLED AT UUO LEVEL ONLY
ILLOUT::JSP T1,ERRPTU
ASCIZ /input /
PUSHJ P,ERNAM ;PRINT "DEVICE XXX"
JSP T1,UUOMES ;PRINT MESSAGE,UUOPC,STOP JOB
ASCIZ / cannot do output/
;ILLEGAL DEVICE DATA MODE (INIT, OPEN, OR SETSTS UUOS)
;CALLED AT UUO LEVEL ONLY
ILLMOD::JSP T1,ERRPTU
ASCIZ /Illegal data mode for /
JRST DEVEXC ;PRINT "DEVICE XXX",UUO PC
;IO UUO TO USER CHANNEL WITH NO PREVIOUS INIT OR OPEN
;CALLED AT UUO LEVEL ONLY
IOIERR::JSP T1,ERRPTU
ASCIZ /IO to unassigned channel/
JRST UUOPCP ;PRINT UUO PC
;ILLEGAL UUO
;CALLED AT UUO LEVEL ONLY
;SERVES TWO PURPOSES - A) TO WARN WHEN MOVING FROM A LOCATION WITH SPECIAL INSTALLATION
;UUOS TO ONE WITH LACKS THEM
;B) TO WARN OF OLD UUO'S WITH NONSKIP "GOOD" RETURNS WHICH
;HAVE BEEN "DE-IMPLEMENTED"
UUOERR::EXCH T1,.UPMP+.UPMUP ;GET UUO PC
TLNN T1,USRMOD ;FROM EXEC?
JRST EMUERR ;YES
EXCH T1,.UPMP+.UPMUP ;PUT THINGS BACK
ILLUUO: PUSH P,.UPMP+.UPMUP ;NOW PUSH USER PC ON STACK JUST LIKE UUO
; (LEAVE STACK UNTOUCHED BEFORE HALT)
; (START PRESERVES PC FLAGS IN LH)
PUSHJ P,GIVRES ;GIVE UP INTERLOCKS
IFN FTPI,<
SIGNAL C$IUUO ;SIGNAL ILLEGAL UUO
SKIPA ;DOESN'T WANT THE TRAP
JRST ERRGOU ;INTERCEPT THE UUO
> ;END FTPI
JSP T1,ERRPTU
ASCIZ /Illegal UUO/
MOVE T2,.UPMP+.UPMUP ;GET UUO PC
SOJA T2,PCPNT ;AND PRINT, PRINT USER UUO PC IF DIFF.
;UUO ERROR-MONITOR ERROR AT UUO LEVEL
;CALLED AT UUO LEVEL ONLY
UUOER1::JSP T1,ERRPTU
ASCIZ /UUO error/
JRST UUOPCP
;HERE ON AN EXEC MODE UUO ERROR
EMUERR: EXCH T1,.UPMP+.UPMUP
CONSZ PI,PI.IPA ;AT UUO LEVEL?
STOPCD .,STOP,UIL, ;++UUO AT INTERRUPT LEVEL
STOPCD .+1,DEBUG,EUE, ;++EXEC UUO ERROR
MOVE J,.CPJOB## ;GET JOB NUMBER
JRST ILLUUO ;PRINT ERROR MESSAGE
;HERE IF THE USER DIES IN GETWRD OR PUTWRD
UADERR::PUSHJ P,GIVRES ;RETURN INTERLOCKS
JSP T1,ERRPTU
ASCIZ /Illegal address in UUO/
JRST UUOPCP
;ILLEGAL INSTRUCTION
;HALT INSTRUCTION IS A SPECIAL CASE WHICH STOPS JOB BUT
;THE USER MAY CONTINUE FROM IT(EFFECTIVE ADR.)
;CALLED AT UUO LEVEL WITH A JRST
ILLINS::
IFN FTKL10!FTKS10,<
LDB T1,[POINT 9,M,8] ;OPCODE
CAIL T1,130 ;WITHIN LONG FLOATING POINT RANGE?
CAILE T1,177
JRST ILLIN1 ;NO, ILLEGAL INSTRUCTION
MOVSI T2,(JS.FPS) ;WANT SIMULATION BIT
SKIPE [M.FPS##] ;SIMULATION ROUTINE LOADED?
TDNN T2,JBTST2##(J) ;AND DOES THE USER WANT SIMULATION?
CAIA ;NO
JRST KALFPS## ;YES, SIMULATE THE KA FP INSTRUCTIONS
IFN FTPI,<
SIGNAL C$IUUO ;SIGNAL ILL INSTRS
CAIA ;PROGRAM ISN'T INTERESTED
JRST ERRGOU ;GO TO THE USER
>
JSP T1,ERRPTU ;TELL THE USER TO FIX THE PROGRAM
ASCIZ /KA10 floating point instruction/
JRST UUOPCP
ILLIN1:>
IFN FTPI,<
SIGNAL C$IUUO ;SIGNAL ILL UUO
SKIPA ;USER DOESN'T WANT THE TRAP
JRST ERRGOU ;GO TO THE USER
>
HLRZ T1,M ;ILLEGAL OPCODE
CAIN T1,254200 ;IS IT A HALT?
JRST HALTI ;YES, PRINT DIFFERENT MESSAGE
IFN FTKI10,<
KIIBEG==105
KIIEND==127
LSH T1,-9 ;MAKE T1=OPCODE
IFN FTKI10,<
MOVSI T2,201704 ;MASK FOR KL10 INST.
>
CAIG T1,KIIEND ;IF TOO LARGE, DON'T SHIFT
LSH T2,-KIIBEG+1(T1) ;SHIFT MASK BY OPCODE
JUMPGE T2,ILLKAI ;KA10 ILL INST IF SIGN NOT 1
KLONLY: JSP T1,ERRPTU
ASCIZ /KL10 only instruction/
JRST UUOPCP
> ;END FTKI10
ILLKAI: JSP T1,ERRPTU
ASCIZ /Illegal instruction/
JRST UUOPCP ;PRINT UUO PC AND STOP JOB
HALTI: JSP T1,ERRPTU
ASCIZ /HALT/
SOS T2,.JDAT+JOBPD1## ;UUOPC=LOC OF HALT+1
PUSHJ P,PCP ;PRINT "USER LOC XXX"
HRR M,.UPMP+.UPMUO ;CHKINT CLOBBERS M
HRRM M,.JDAT+JOBPD1## ;SAVE EFFECTIVE ADDRESS OF HALT
PUSH P,U
PUSHJ P,TTYSRC## ;GETTTY
STOPCD .,STOP,LNT, ;NONE?!
JUMPE U,HALTI2 ;JUMP IF JOB DETACHED
POP P,U
PUSHJ P,TSETBI## ;CLEAR TYPE-AHEAD
PUSHJ P,HOLDW## ;START TTY WITH STANDARD RESPONSE,, STOP
;JOB, LEAVE TTY IN MONITOR MODE
;DO NOT SET ERROR BIT SO CAN CONTINUE
HALTI1: PUSH P,.JDAT+JOBPD1## ;PUT USER RETURN ON END OF PD LIST
JRST USRXIT## ;RETURN TO USER IN CASE HE TYPES CONT COMMAND
HALTI2: POP P,U
PUSHJ P,CRLF## ;HERE TO HANDLE HALT IN DET'D JOB
PUSHJ P,ESTOP3## ;STOP JOB WITH CONTINUABILITY
PUSHJ P,WSCHED## ;WAIT FOR USER
JRST HALTI1 ;RESUME NORMAL FLOW
;ILLEGAL TRAP INSTRUCTION
ILLTIN::MOVE P,[MJOBPD##,,.JDAT+JOBPDL##]
PUSH P,.UPMP+.UPMUP
JSP T1,ERRPTU
ASCIZ /Illegal trap instruction/
JRST UUOPCP ;PRINT TRAP INSTR PC AND STOP THE JOB
SUBTTL I/O ERROR HANDLING ROUTINES
;ROUTINE FOR HUNG IO DEVICE
;CALL MOVE F,ADDRESS OF DEVICE DATA BLOCK
; PUSHJ P,DEVHNG
DEVHNG::PUSHJ P,SVEUF## ;MAKE SURE JOB DATA AREA IS ADDRESSABLE
PUSHJ P,CLRACT## ;TURN OFF IO DEVICE ACTIVE BIT IN
;MEMORY AND S
LDB J,PJOBN## ;JOB NUMBER
JUMPE J,DEVHN2
IFN FTPI,<
MOVEI T1,IR.HNG ;HUNG CONDITION
TSNN T1,DEVPSI##(F) ;PROGRAM ENABLED?
JRST DEVHN1 ;NO
PUSHJ P,PSIDVB## ;SIGNAL HUNG DEVICE
TRO S,IOIMPM!IOBKTL!IODERR!IODTER ;ALL ERRORS
PUSHJ P,SETIOD## ;GET THE JOB GOING
PJRST STOIOS## ;STORE BITS AND RETURN
>
DEVHN1: MOVSI T1,JERR ;FLAG SO USER DOESN'T
IORM T1,JBTSTS(J) ;GET IF TRAP ENABLED
DVHN1A: IFN FTMP,<
CPLOCK (SCD) ;GET SCHEDULAR LOCK
>
MOVEI T1,STOPQ##
DPB T1,PJBSTS##
PUSHJ P,ANYCPU## ;IS HE RUNNING ANYWHERE NOW?
SKIPA ;YES MUST DELAY HANGING HIM
JRST DVHN1C ;NO, CAN STOP HIM NOW
MOVEI T2,1 ;GET A WORRD
PUSHJ P,GETWDS## ;OF FREE CORE
JRST DVHN1C ;FAILED BLAST JOB ANYWAY
MOVEM F,(T1)
HRLM J,(T1) ;SAVE J
MOVE T2,.CPCPN##
DPB T2,[POINT 3,T1,3] ;CPU IS US
TLO T1,400000
MOVEI T2,1 ;IN A TIC
HRLI T2,DVHN1B
SYSPIF
IDPB T2,CLOCK##
IDPB T1,CLOCK##
SETOM CLKNEW##
SYSPIN
IFN FTMP,<
CPUNLK (SCD)
>
POPJ P, ;AND RETURN FOR NOW
DVHN1B: HLRZ J,(T1) ;RESTORE J
HRRZ F,(T1) ;AND F
MOVEI T2,(T1) ;RETURN FREE CORE
MOVEI T1,1
PUSHJ P,GIVWDS##
PUSHJ P,SVEUB## ;MAKE JOB ADDRESSABLE
JRST DVHN1A ;CHECK TO SEE IF HE'S STILL HERE
DVHN1C: PUSH P,F ;GIVRSC CLOBBERS F
PUSHJ P,GIVRSC ;RETURN RESOURCES, COULD HAVE SOME, IF STR YANKED
POP P,F
MOVEI T1,STOPQ##
DPB T1,PJBSTS##
IFN FTMP,<
CPUNLK (SCD)
>
DEVHN2: JSP T1,ERRDEV
ASCIZ /Hung /
JRST DEVEXC
;BAD DECTAPE DIRECTORY
;CALLED AT INTERRUPT AND UUO LEVELS WITH F AND J SETUP
BADDIR::PUSHJ P,SVEUF## ;MAKE JOB DATA AREA ADDRESSABLE
JSP T1,ERRPNT
ASCIZ /Bad directory for /
;ROUTINE TO PRINT "DEVICE XXX; EXEC CALLED FOR EXEC/USER YYY"
;THEN STOP JOB
;TO BE USED BY DEVICE DEPENDENT ERROR MESSAGES AFTER JSP T1,DEVERR
DEVEXC::PUSHJ P,ERNAM ;PRINT "DEVICE XXX"
SKIPE JBTADR##(J) ;CHECK FOR JOB IN CORE
JRST EXCALP ;PRINT "EXEC CALLED FROM EXEC/USER LOC YYY"
JRST PCSTOP ;JUST STOP THE JOB
;ROUTINE TO HALT A JOB WHEN A DEVICE IS NOT READY FOR I/O
;CALLED FROM XXXSER AT UUO LEVEL
;CALL MOVE F,ADDR. OF DEV. DDB
; PUSHJ P,HNGSTP
;WILL DISPATCH TO USER'S AREA IF JOBINT IS NON-0
HNGSTP::PUSH P,M
PUSHJ P,HNGSTX
PJRST MPOPJ##
HNGSTX: PUSHJ P,SAVE3## ;SAVE P1-P3
SKIPE P3,DEVEVM(F) ;DOES DEVICE HAVE EVM?
SETO P3, ;NO
PUSHJ P,RTNEVM## ;RETURN ANY EVM DEVICE HAS FOR I/O
; P3=-1 IF DEVICE HAD NO EVM, 0 IF IT DID
SOS .JDAT+JOBPD1## ;BACK UP PC
MOVEI T4,.ERIDV ;DEV OR INTERCEPT
IFN FTPI,<
TLO M,(1B0)
PUSHJ P,PSIJBI## ;CALL PSISER
PJSP P1,HNGST1 ;P1 NON-ZERO TO INDICATE INTERCEPTING
TLZ M,(1B0)
>
SETO T2, ;MAKE T2 NON-ZERO SO LATER CHECKS WILL WORK
LDB T3,PJOBN##
SKIPE T3,JBTSTS##(T3)
TRNN T3,JS.ASA
PUSHJ P,CHKINT ;SEE IF SET UP
SETZB T2,T3 ;NO
MOVE P1,T2 ;SAVE LOCATION
PUSHJ P,DOINT ;PREPARE INTERCEPT
JUMPN T2,HNGST1 ;IF NOT INTERCEPTING
PUSHJ P,INCPD1##
HNGST1: JUMPL T3,HNGST3 ;YES, DOES HE WANT THE ERROR MESSAGE?
PUSH P,J ;YES
PUSH P,W
PUSH P,S
PUSH P,U
PUSH P,F ;SAVE DEV'S S WORD & DDB
LDB J,PJOBN## ;GET JOB NUMBER
PUSHJ P,FNDPDS## ;FIND PDB AND PUT IT'S ADDRESS IN W
; IF NONE HALT.
EXCH F,0(P) ;GET F FROM DEVICE
LDB T1,PDVSTA## ;GET JOB'S LOCATION
EXCH F,0(P) ;GET F FOR TTY BACK
JUMPE T1,HNGST2 ;CENTRAL SITE IF 0 (DISK)
IFN FTNET,<
PUSHJ P,STBOPR## ;GET OPR LINE
>
IFE FTNET,<
MOVE U,OPRLDB##
LDB T1,LDPLNO##
>
SKIPA U,LINTAB##(T1) ;GET LDB ADDR
HNGST2: MOVE U,OPRLDB## ;CENTRAL STA OPR
PUSHJ P,INLMES## ;OUTPUT START OF MESSAGE
ASCIZ /
%ππProblem on /
PUSHJ P,ERNAM ;PRINT PHYSICAL DEVICE NAME (USING -1(P))
PUSHJ P,INLMES## ;LOGICAL DEVICE OPR
ASCIZ / for job /
PUSHJ P,PJOB##
PUSHJ P,CRLF##
PUSHJ P,TTYFUW## ;FIND CURRENT JOB'S TTY
PUSHJ P,CRLF## ;START A NEW LINE
PUSHJ P,ERNAM ;PRINT "DEVICE XXX"
PUSHJ P,INLMES## ;AND MSG.
ASCIZ /, OPR/
IFN FTNET,<
EXCH F,(P) ;GET POINTER DDB
LDB T1,PDVSTA## ;GET DEVICES LOCATION
EXCH F,(P)
PUSHJ P,CVTSBT## ;CONVERT TO SIXBIT
MOVE T2,T1 ;GET SIXBIT FOR PRNAME
PUSHJ P,PRNAME ;AND PRINT IT
>
PUSHJ P,INLMES##
ASCIZ / action requested/
MOVEI T1,TTYSTR## ;UNLESS ERROR INTERCEPTING
SKIPN P1 ;CALL HOLD0 (STOP JOB,START TTY)
HNGST8: MOVEI T1,HNGST4 ;SET UP ROUTINE TO CALL
PUSHJ P,(T1) ;START TTY TYPING ERR MESSAGE
; LEAVE IN COMMAND MODE
;DO NOT SET JOB ERROR SO CAN CONTINUE
POP P,F ;BRING BACK DEV DDB & S WORD
POP P,U
POP P,S
POP P,W
POP P,J
JUMPN P1,HNGST3 ;DO INTERCEPT IF WANTED
PUSHJ P,WSCHED## ;RESCHEDULE
MOVSI T1,DVDSK ;GET BIT TO TEST
TDNN T1,DEVMOD(F) ;IS THIS A DISK?
JRST HNGST9 ;NO, SKIP THIS
PUSHJ P,CHEKU## ;YES, WAS F/S YANKED?
PJRST DEVHNG ;YES, SAY IT'S HUNG
HNGST9: AOJN P3,CPOPJ## ;DEVICE HAVE EVM WHEN THE ERROR OCCURRED?
MOVE M,-5(P) ;RESTORE M FOR ADDRESS CHECK
PJRST RSTEVM## ;YES, RESTORM EVM FOR I/O
HNGST3: MOVEI T1,DEPOND!DEPIND ;NON-BLOCKING I/O NOT DONE BITS
ANDCAM T1,DEVAIO(F) ;CLEAR THEM SO THAT IN/OUT UUOS WILL WIN
MOVEI P1,1(M) ;SAVE 1(INTERCEPT LOC)
LDB T1,PIOMOD## ;MODE
MOVE T4,DEVADV(F)
TLNN T4,DEPADV
CAIL T1,SD ;DUMP?
JRST HNGST7 ;YES, NO BUFFERS TO FIX
HRR M,DEVBUF(F) ;BUFFERED, FIX UP BUFFER HDR
TLNE S,IO ; SO REPEATING THE UUO WILL WIN
HLR M,DEVBUF(F) ; (THEY WERE ALREADY ADVANCED)
HRRZ T4,M ;SAVE LOCATION OF THE HDR
JUMPE T4,HNGST7 ;JUMP IF NO BUFFERS YET SET UP
PUSHJ P,GETWRD## ;GET LOCATION OF FIRST BUFFER
JRST HNGST7 ;ADDRESS CHECK - CAN'T FIX THE RING
MOVE P2,T1 ;P2=ADDRESS OF FIRST BUFFER
MOVEI T3,10000 ;END OF LOOP INSURANCE
HNGST5: HRR M,T1 ;M=ADDRESS OF THIS BUFFER
PUSHJ P,GETWRD## ;GET THE ADDRESS OF THE NEXT ONE
JRST HNGST7 ;ADDRESS CHECK, FORGET IT
CAIE P2,(T1) ;THE ONE WE WANT?
SOJGE T3,HNGST5 ;NO, STEP TO NEXT
JUMPL T3,HNGST7 ;YES, JUMP IF RING WAS NOT CLOSED
HRR P2,M ;P2=POINTER TO NEXT BUFFER
TLO T1,IOUSE ;INDICATE "FULL" FOR TEST AT INPUT
PUSHJ P,PUTWDU## ;STORE THAT
HRR M,T4 ;RESTORE HEADER ADDRESS
MOVE T1,P2 ;T1=DEADVANCED BUFFER POINTER
PUSHJ P,PUTWDU## ;STORE THAT IN THE HDR
HNGST7: HRRI M,(P1) ;M=ADDRESS OF THIRD WORD OF INT. BLOCK
PUSHJ P,GETWDU## ;FETCH IT
HLR T1,.UPMP+.UPCTA
SKIPL M ;SKIP IF PSISER TRAP
PUSHJ P,PUTWDU## ;STORE FOR INTERRUPT ROUTINE
QKUSXT::
ERRGOU::HRRI P,.JDAT+JOBPD1## ;SET P FOR NORMAL EXIT
;(POP P,UUO0 ; JRST @UUO0)
SETZB F,.CPISF## ;NO LONGER AT SCHEDULER LEVEL
SETZM .CPSCF## ;CLEAR FORCED RESCHEDULE FLAG
NTGIVE ;RETURN NETWORK INTERLOCK
PJRST USRXIT## ;LET UUOCON RETURN TO USER
HNGST4:IFN FTJCON,<
MOVEI T1,JDCON ;NO ERROR INTERCEPT
IORM T1,JBTSTS##(J) ; SO SET DEV CONT BIT
>
PUSHJ P,CRLF## ;PRINT A CRLF
PUSH P,TTYTAB##(J) ;MAKE THIS JOB LOOK DETACHED
SETZM TTYTAB##(J) ; SO IT'S TERMINAL IS NOT PUT
; AT COMMAND LEVEL.
PUSHJ P,STOP1C## ;STOP JOB-SETUP TO RESCHEDULE
; BUT DO NOT CALL WSYNC
POP P,TTYTAB##(J) ;ALL TTYSRC TO WIN AGAIN
POPJ P,0 ;RETURN
;CHKINT -- ROUTINE TO SETUP FOR JOBINT USAGE
;CALL: MOVEI T4,ERROR TYPE (CLASS)
; PUSHJ P,,CHKINT
;SKIP RETURNS M = RELATIVE BLOCK ADDRESS+2 (WHERE OLD PC IS STORED)
; T1 = NEW PC
; T3 = CONTENTS OF BITS,,CLASS
;STORES ERROR TYPE IN BLOCK+3.
IFN FTCCIN!FTDAEM,<
CHKINT::SKIPN JBTADR##(J) ;JOB HAVE CORE?
POPJ P, ;NO - THEN NO JOBINT
MOVE T1,JBTSTS##(J) ;JOB STATUS
TLNN T1,SWP ;IS JOB SWAPPED OR
TRNE T1,JS.ASA ;EXEC MODE UUO IN PROGRESS?
POPJ P, ;YES, DON'T TRAP
HRR M,.JDAT+JOBINT## ;GET ERROR LOCATION
; SET M FOR GETWRD/PUTWRD
HRRZ T1,M ;CHECK FIRST WORD OF INTERRUPT VECTOR
PUSHJ P,FLTST## ;IN-CORE?
POPJ P, ;NO
ADDI T1,3 ;LAST WORD OF VECTOR
PUSHJ P,FLTST## ;IN-CORE?
POPJ P, ;NO
TRNE M,-1 ;NO INTERRUPT IF JOBINT NOT SET
PUSHJ P,GETWRD## ;GET NEW PC
POPJ P, ;ADDRESS CHECK - GIVE UP
HRL T4,T1 ;SAVE NEW PC
PUSHJ P,GETWR1## ;GET BITS,,CLASS
POPJ P, ;OUT OF BOUNDS
MOVE T3,T1 ;SAVE THOSE
PUSHJ P,GETWR1## ;GET OLD PC
POPJ P, ;ADDRESS CHECK - GIVE UP
TRNE T4,-1 ;IF SPECIAL,
TRNE T3,(T4) ; SEE IF USER OMITTED IT
SKIPE T1 ;SEE IF IN USE ALREADY
POPJ P, ;YES - GIVE UP
PUSHJ P,GETWR1## ;GET THE OLD WORD
POPJ P,0 ; ADDRESS CHECK
TLO T1,(T4) ;TURN ON THE NEW BIT
PUSHJ P,PUTWRD## ; STORE ERROR BITS
POPJ P, ;ADDRESS CHECK - GIVE UP
HLRZ T1,T4 ;GET NEW PC
JUMPE T1,CPOPJ## ;GIVE UP IF JUNK
SOJA M,CPOPJ1## ;OK RETURN
;DOINT -- ROUTINE TO PERFORM THE JOBINT
;CALL: MOVE T1,NEW PC
; MOVEI M,USER VIRTUAL ADDRESS OF INTERRUPT BLOCK + 2
;RETURN WITH JOBPD1 UPDATED
DOINT:: JUMPE T2,CPOPJ## ;IF NO BLOCKS, GIVE UP
EXCH T1,.JDAT+JOBPD1## ;STORE NEW PC
TLO T1,(XC.USR) ;MAKE SURE USER MODE IS ON
HLLM T1,.JDAT+JOBPD1## ;STORE FLAGS
PJRST PUTWDU## ;STORE OLD PC AND RETURN
>;END IFN FTCCIN!FTDAEM
;ROUTINE TO PRINT "SWAP READ ERROR"
;CALLED FROM SWAPPER AT CLOCK LEVEL (USUALLY)
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,ERRSWP
; ALWAYS RETURN TO SWAPPER
ERRSWP::PUSHJ P,SVEUB## ;LOAD UBR
MOVSI T1,JERR ;SET JERR SO WE DO NOT
IORM T1,JBTSTS##(J) ;TRY TO INTERCEPT
JSP T1,ERRPNT ;PRINT MESSAGE
ASCIZ /Swap read error/
PJRST PCSTOP ;START TTY AND SET JERR BIT SO
; JOB CANNOT CONTINUE. PI 7 WILL NOT
; BE REQUESTED SINCE SWAPPING JOB CANNOT
; BE CURRENT JOB.
;ERRPNT PUSHED TWO AC'S. PCSTOP REMOVES THEM
SUBTTL COMMON ERROR MESSAGE ROUTINES
;COMMON ERROR MESSAGE SETUP ROUTINES
;CALL: JSP T1,ERRPTU, ERRDEV, OR ERRPNT
; ASCIZ /message/
; RETURNS HERE WITH F SAVED 0(P)
; C(F)=TTYDDB, U TO TTY OUTPUT BUFFER POINTER
; J=JOB NUMBER, W=ADDR OF PDB
;USE ERRPTU IF AT UUO LEVEL FOR SURE
;ERRDEV IF ERROR FOR AN ASSIGNED DEVICE AT ANY LEVEL
;ERRPNT WITH J ALREADY SET TO OFFENDING JOB NUMBER
;THE JSP CALL IS USED IN CASE PUSHDOWN SPACE BECOMES CRITICAL
;AGAIN AND ERRPNT HAS TO WIPE EXISTING LIST OUT
ERRPTU::SKIPA J,.CPJOB## ;BLAME CURRENT JOB IF NOT 0.
ERRDEV::LDB J,PJOBN## ;JOB NO. FROM DEVICE DATA BLOCK
ERRPNT::PUSHJ P,FNDPDB## ;FIND PDB FOR THIS JOB
HRRZ W,JBTPDB## ;USE NULL JOB'S PDB
SKIPN J ;ERROR IN NULL JOB?
SETOM .CPNJE## ;YES, SET FLAG FOR ERROR IN NULL JOB
; SO STATE OF NULL JOB WILL BE REESTABLISHED
; WHEN IS IT RUN AGAIN(SEE CLOCK1)
CAILE J,JBTMAX## ;JOB NUMBER OR SEGMENT NUMBER
STOPCD .,STOP,SOR, ;++SEG OUT OF RANGE
PUSH P,U ;SAVE CALL TO ERROR(JSP U,ERROR)
PUSH P,F ;SAVE ADR. OF DEV. DATA BLOCK
PUSH P,T1 ;SAVE RETURN FROM ERRPNT
MOVE T1,JBTSTS##(J)
TDNE T1,[JERR,,JS.ASA]
JRST ERRPT1
IFN FTPI,<
PUSHJ P,USREIJ## ;SIGNAL USER ERROR
JRST ERRGOU
>
IFN FTCCIN!FTDAEM,<
MOVEI T4,.EREIJ ;DOES THIS JOB WANT
PUSHJ P,CHKINT ; TRAP ALL ERRORS?
JRST ERRPT1 ;NO--BOMB HIM OUT
JUMPGE T3,ERRPT1 ;JUMP IF HE WANTS MESSAGE
MOVE T2,M ;NO MESSAGE
PUSHJ P,DOINT ;PREPARE INTERCEPT
;***NEED TO STORE ERROR CODE***
PJRST QKUSXT ;BACK TO USER
>
ERRPT1: PUSHJ P,TTYERP## ;FIND TTY FOR THIS ERROR (VIA J)
PUSHJ P,ERINDJ ;ERROR IN DETACHED JOB
PUSHJ P,INLMES##
ASCIZ /?
/
PUSHJ P,PRQM## ;PRINT QUESTION MARK ON NEXT LINE
; FOR BATCH AND SCRIPT
PJRST INLMES## ;PRINT MESSAGE SPECIFIED BY CALLER
; AND RETURN TO LOC. AFTER MESSAGE
ERINDJ::JUMPE J,ERINNJ ;JUMP IF NULL JOB
PUSHJ P,INLMES## ;PRINT ERROR MESSAGE
ASCIZ /?Error in detached job/
PUSHJ P,PRJBNM ;PRINT JOB # AND PROGRAM NAME
PJRST CRLF## ;PRINT <CRLF> AND RETURN
ERINNJ: PUSHJ P,INLMESS## ;PRINT ERROR MESSAGE
ASCIZ /?Error in job 0 (null job)
/
POPJ P,
;ROUTINE TO PRINT UUO PC AND STOP JOB
;IF IN USER MODE PC WILL PRINT AS "AT USER LOC XXX"
;IF IN EXEC MODE "AT EXEC LOC XXX; EXEC CALLED FORM EXEC/USER/ LOC YYY
UUOMES::PUSHJ P,CONMES## ;PRINT MESSAGE POINTED TO BY T1
UUOPCP::MOVE T2,.JDAT+JOBPD1## ;UUO PC STORED IN JOB DATA AREA
; FIRST LOC ON PD LIST
SOJA T2,PCPNT ;DECREMENT TO POINT TO UUO IN USER AREA
;ROUTINE TO PRINT ONE OF THREE MESSAGES AND STOP JOB
;1) "AT EXEC LOC XXX; EXEC CALLED FROM EXEC LOC YYY"
;2) "AT EXEC LOC XXX; EXEC CALLED FORM USER LOC YYY"
;3) "AT USER LOC YYY"
;CALL: MOVE T2, XXX ;WITH PC FLAGS IN LH
; PUSHJ P,PCPNT
; NEVER RETURN IF AT UUO LEVEL
PCPNT::IFN FTWATCH,<
TLNE T2,USRMOD ;MAKE SURE CONTROL-T
HRRM T2,JBTPC##(J) ; GIVES CORRECT ANSWER
>
PUSHJ P,PCP ;PRINT " AT EXEC XXX" OR " AT USER "
TLNE T2,USRMOD ;WAS PC IN USER MODE?
JRST PCSTOP ;YES, ENOUGH INFO.
;ROUTINE TO PRINT "; UUO AT [EXEC or USER] PC XXXXXX" AND STOP JOB
;CALL: PUSHJ P,EXCALP
; NEVER RETURNS IF AT UUO LEVEL
EXCALP::PUSHJ P,INLMES##
ASCIZ /; UUO/
MOVE T2,.JDAT+JOBPD1## ;UUO PC IN JOB DATA AREA
SUBI T2,1 ;BACK IT UP TO POINT TO UUO
PUSHJ P,PCP ;PRINT "EXEC LOC " OF USER LOC
PCSTOP::PUSH P,U
JUMPN J,PCSTP5 ;NULL JOB?
PUSHJ P,TTYERP ;YES--FIND THE OPR
JRST PCSTP6 ;WE HAVE A VALID LINE
STOPCD .,STOP,NJT, ;NULL JOB HAS TTY
PCSTP5: PUSHJ P,TTYSRC## ;SET TTY
STOPCD .,STOP,LN1, ;NONE?!
JUMPE U,PCSTP2 ;IS IT DETACHED?
PCSTP6: SKIPE T1,F ;SKIP IF NO DDB
LDB T1,PJOBN## ;GET JOB #
CAMN T1,J ;IS THIS THE TTY OF THE LOOSER
PUSHJ P,TSETBI## ;CLEAR TYPE-AHEAD
PCSTP2:
IFN FTPI!FTCCIN!FTDAEM,<
MOVE T1,JBTSTS##(J) ;GET JOB STATUS
TDNE T1,[JERR,,JS.ASA] ;CAN WE INTERCEPT
JRST PCSTP1 ;NO--STOP JOB
>
IFN FTPI,<
PUSHJ P,PSIERR##
JRST PCSTP4 ;AT CLOCK LEVEL, CATCH IT AT CIPXIT
JRST ERRGOU ;AT UUO LEVEL, CATCH IT AT USRXIT
>
IFN FTCCIN!FTDAEM,<
MOVEI T4,.EREIJ ;DOES THIS JOB WANT
CAMN J,.CPJOB## ;CANT INTERCEPT IF ON CLOCK LEVEL
PUSHJ P,CHKINT ; TRAP ALL ERRORS?
JRST PCSTP1
PUSHJ P,DOINT ;PREPARE INTERCEPT
PJRST QKUSXT ;BACK TO USER
>
PCSTP1: JUMPN U,PCSTP3 ;IS JOB DET'D
POP P,U
PUSHJ P,CRLF## ;YES,
PUSHJ P,ESTOP## ;STOP JOB
JRST ECONT ;RESUME FLOW
PCSTP3: PUSHJ P,HOLD## ;STOP JOB SET ERROR BIT
PCSTP4: POP P,U
;HERE TO CONTINUE AFTER ERROR (IF AT PI LEVEL OR USER TYPES CONT)
ECONT: POP P,F ;RETURN ONLY IF AT INTERRUPT LEVEL
JRST TPOPJ## ;REMOVE ERROR CALL AND RETURN
;ALTHOUGH U WAS PUSHED, POP INTO T1, PERSERVE LINE NUMBER
;ROUTINE TO TYPE A NUMBER AS HALFWORDS SEPARATED BY COMMAS.
;CALL: MOVE T1,NUMBER
; PUSHJ P,HWDPNT
; RETURN
HWDPNT::PUSH P,T1 ;SAVE T1 FOR RH
HLRZS T1 ;KEEP JUST LH
PUSHJ P,OCTPNT ;PRINT AS 6 OCTAL DIGITS
PUSHJ P,INLMES ;PRINT THE TWO COMMAS
ASCIZ/,,/ ;...
POP P,T1 ;RESTORE T1 FOR RH
PJRST OCTPNT ;PRINT RH AND RETURN
;ROUTINE TO PRINT PC AS:
;1) "EXEC PC XXX" OR "USER PC XXX"
;CALL: MOVE T2,PC TO PRINT(LH=PC FLAGS)
; PUSHJ P,PCP
XMODE: ASCIZ / at exec PC /
UMODE: ASCIZ / at user PC /
PCP:: MOVEI T1,XMODE ;ASSUME PC IN EXEC MODE
TLNE T2,USRMOD ;IS IT?
PCPU:: MOVEI T1,UMODE ;NO, USER MODE
PUSHJ P,CONMES## ;PRINT ONE OR OTHER
HRRZ T1,T2 ;PRINT RIGHT HALF IN OCTAL
; FALL INTO OCTPNT
;ROUTINE TO PRINT 6 DIGIT OCTAL NUMBER
;CALL: MOVEI LINE,LINE DATA BLOCK ADDRESS FOR TTY
; HRR T1, OCTAL NUMBER
; PUSHJ P,OCTPNT
; RETURN T2,PRESERVED,T1 DESTROYED
OCTPNT::HRLZ T1,T1 ;MOVE TO LH FOR ROTATING
TRO T1,700000 ;SETUP AN END FLAG
OCTP1: ROT T1,3 ;GET NEXT OCTAL DIGIT
TLNN T1,777777 ;WAS THAT FLAG?
POPJ P, ;YES, DO NOT PRINT IT
PUSH P,T1 ;SAVE T1 OVER I/O ROUTINE
PUSHJ P,PRTNUM ;NO, PRINT OCTAL DIGIT
POP P,T1 ;RESTORE T1
HRRI T1,0 ;CLEAR RH
JRST OCTP1 ;GET NEXT OCTAL DIGIT
;ROUTINE TO ADD 1 TO T1 AND PRINT DECIMAL
;SAME CALL AS OCTPNT
DECP1:: AOJA T1,RADX10 ;ADD 1 AND GO PRINT
;ROUTINE TO PRINT DECIMAL
;CALL: SAME AS OCTPNT
;T2: PRESERVED
RADX10::PUSH P,T2 ;SAVE T2
PUSHJ P,PRTDIG ;PRINT DECIMAL DIGITS
PJRST T2POPJ## ;RESTORE T2 AND RETURN
;RECURSIVE DECIMAL PRINT ROUTINE
;CALL: MOVE T1,DECIMAL NO.
; PUSHJ P,PRTDIG
PRTDIG::IDIVI T1,12 ;DIVIDE BY 10
HRLM T2,(P) ;RT ON PD LIST
JUMPE T1,.+2 ;FINISHED?
PUSHJ P,PRTDIG ;NO, CALL S OR F
PRTNMM: HLRZ T1,(P) ;YES, GET LAST NUMBER
PRTNUM: MOVEI T3,"0"(T1) ;CONVERT TO ASCII
PJRST COMTYO## ;AND TYPE IT OUT
;RECURSIVE OCTAL PRINT ROUTINE
;CALL: SAME AS PRTDIG
PRTDI8::IDIVI T1,10 ;DIVIDE BY 8
HRLM T2,(P) ;PUT ON STACK
JUMPE T1,PRTNMM ;FINISHED?
PUSHJ P,PRTDI8 ;NO - LOOP
PJRST PRTNMM ;OUTPUT
;SUBROUTINE TO PRINT 22 BIT OCTAL ADDRESS
;CALL: MOVE T1,22 BIT ADDRESS
; PUSHJ P,PRT22A
; ALWAYS RETURN
PRT22A::PUSH P,T1 ;SAVE 22 BIT ADDRESS
HLRZ T1,(P) ;GET HIGH ORDER HALF
JUMPE T1,PRT22B ;IS IT 0 (USUALLY EXCEPT BIG SYSTEMS)
PUSHJ P,PRTDI8 ;NO, PRINT AS LEADING 0 SUPPRESSED OCTAL
PRT22B: POP P,T1 ;GET LOW ORDER HALF
PJRST OCTPNT ;PRINT AS NON ZERO SUPPRESSED OCTAL (RH ONLY)
;ROUTINE TO PRINT "DEVICE XXX"
;CALL MOVE U,ASCII OUTPUT BYTE POINTER
; PUSH P,F
; PUSHJ P,ERNAM
ERNAM:: PUSHJ P,INLMES##
ASCIZ /device /
SKIPN T2,-1(P) ;IS F = 0?
PJRST PRNAM1 ;YES, MESSAGE WITHOUT NAME
MOVSI T1,DVDSK ;DEVICE IS DISK BIT
TDNN T1,DEVMOD(T2) ;SKIP IF DISK
JRST ERNAM1 ;NOT DISK, GET PHYSICAL DEVICE NAME
SKIPN T1,DEVUNI##(T2) ;GET CURRENT UNIT DATA BLOCK ADDRESS
SKIPE T1,DEVFUN##(T2) ;IF UNIT REMOVED, GET SAVED ADDRESS
SKIPA T2,UNINAM##(T1) ;GET PHYSICAL UNIT NAME AND SKIP TO PRNAM1
ERNAM1: MOVE T2,DEVNAM(T2) ;NO, GET DEVICE NAME
;ROUTINE TO PRINT SIXBIT NAME
;CALL MOVE U,ASCII OUTPUT BYTE POINTER
; MOVE T2,NAME
; PUSHJ P,PRNAME
PRNAM1: MOVEI T1,0
LSHC T1,6 ;SHIFT IN NEXT CHAR.
MOVEI T3,40(T1) ;ASCII VERSION INTO CHREC FOR OUTCHS
PUSHJ P,COMTYO## ;OUTPUT CHARACTER
PRNAME::JUMPE T2,CPOPJ##
JRST PRNAM1
;ROUTINE TO PRINT SIXBIT WORD WITH TRAILING SPACES
;CALL: SAME AS PRNAME.
PRSIXB::MOVEI T3,6
PUSH P,T3
PRSIX0: SETZ T3,
ROTC T2,6
ADDI T3,40
PUSHJ P,COMTYO##
SOSLE (P)
JRST PRSIX0
JRST T3POPJ##
LIT
ERREND: END